2

I have a quicksort method that i implemented myself. i give an array of objects to that method. how do i use a comparator to tell the method which attribute the objects will be sorted by? I have googled around and found out how to implement a comparator, but not how to use it in the search method as every example ive found just used arrays.sort().

i need different getter-methods to get to the different attributes, i dont see how a comparator helps with that?

i just need a little help to kickstart the whole thing, or maybe someone can manage to find a good example online?

    public WifiData[] qsortSSID(WifiData[] array, int left, int right){
    int ll=left;
    int rr=right;

        if (rr>ll){
            String pivot=array[(ll+rr)/2].getSSID();
            //System.out.println(pivot);
            while (ll <=rr){
                //finde erstes element >= pivot
                while(ll<right && array[ll].getSSID().compareTo(pivot) < 0){
                    ll +=1;
                }
                //finde letztes elemtn kleiner gleich pivot
                while(rr>left && array[rr].getSSID().compareTo(pivot) > 0){
                    rr -=1;
                }
                if (ll <=rr){
                    swap(array, ll ,rr);
                    ll +=1;
                    rr -=1;

                }
            }
            if (left < rr){
                qsortSSID(array,left,rr);

            }
            if (ll<right){
                qsortSSID(array,ll,right);
            }
        }



    return array;
}
banzai
  • 55
  • 1
  • 8
  • 2
    Read [the documentation](https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html). Call `compareTo` and it returns an `int` that will tell you which object is "bigger". – Boris the Spider Apr 12 '15 at 17:01
  • 1
    Can you post your code? – CCovey Apr 12 '15 at 17:03
  • (a) why do you implement your *own* method? The current sort method is very much optimized, and (b) please show your implementation... – Willem Van Onsem Apr 12 '15 at 17:04
  • i made my own because the task said to. this is for school and i figured having you make it for me is just plain cheating. – banzai Apr 12 '15 at 17:08
  • okay now i edited it. im supposed to sort it once by ssid, and once by mac and im supposed to give my sort method a comparator to tell it which one to sort it by – banzai Apr 12 '15 at 17:10
  • i have to use getSSID to get to the SSID, and getMac to get to the mac, what does a comparator have to with that? – banzai Apr 12 '15 at 17:17

2 Answers2

3

WifiData should implement Comparable<WifiData> interface by comparing the SSID of this and other.

The signature of your method would then become:

public Comparable[] qsort(Comparable[] array, int left, int right)

and the implementation will be more abstract, so:

String pivot=array[(ll+rr)/2].getSSID();

will become:

Comparable pivot=array[(ll+rr)/2];

and

while(ll<right && array[ll].getSSID().compareTo(pivot) < 0){

will become:

while(ll<right && array[ll].compareTo(pivot) < 0){

etc.

Example:

class WifiData implements Comparable<WifiData> {
    String SSID;

    public String getSSID() {
        return SSID;
    }

    @Override
    public int compareTo(WifiData o) {
        return this.SSID.compareTo(o.getSSID());
    }

    public Comparable[] qsort(Comparable[] array, int left, int right){
        int ll=left;
        int rr=right;

        if (rr>ll){
            Comparable pivot = array[(ll+rr)/2];
            while (ll <=rr){
                while(ll<right && array[ll].compareTo(pivot) < 0){
                    ll +=1;
                }
                while(rr>left && array[rr].compareTo(pivot) > 0){
                    rr -=1;
                }
                if (ll <=rr){
                    swap(array, ll ,rr);
                    ll +=1;
                    rr -=1;
                }
            }
            if (left < rr){
                qsort(array,left,rr);

            }
            if (ll<right){
                qsort(array,ll,right);
            }
        }
        return array;
    }

    void swap(Comparable[] arr, int l, int r) {
        Comparable t = arr[l];
        arr[l] = arr[r];
        arr[r] = t;
    }
}

UPDATE
After reading your comment below your question is clearer. What you should do is use a Comparator: you can implement different Comparators, each of which sorts by a different property.

See the following example:

class WifiData {
    String SSID;

    public String getSSID() {
        return SSID;
    }

    // example how to use it
    public static void main(String[] args) {
        Comparator<WifiData> comp = new SSIDComparator();
        WifiData[] arr = new WifiData[10];
        // ... fill the array
        arr = qsort(arr, 0, arr.length-1, comp);        
    }

    public static WifiData[] qsort(WifiData[] array, 
                                    int left, 
                                    int right,                        
                                    Comparator<WifiData> comp){
        int ll=left;
        int rr=right;

        if (rr>ll){
            WifiData pivot = array[(ll+rr)/2];
            while (ll <=rr){
                // that's how we'll use the comparator:
                while(ll<right && comp.compare(array[ll], pivot) < 0){
                    ll +=1;
                }
                while(rr>left &&  comp.compare(array[rr], pivot) > 0){
                    rr -=1;
                }
                if (ll <=rr){
                    swap(array, ll ,rr);
                    ll +=1;
                    rr -=1;
                }
            }
            if (left < rr){
                qsort(array,left,rr, comp);

            }
            if (ll<right){
                qsort(array, ll, right, comp);
            }
        }
        return array;
    }    

    // an example of Comparator that sorts by SSID
    static class SSIDComparator implements Comparator<WifiData>{
        @Override
        public int compare(WifiData o1, WifiData o2) {
            return o1.getSSID().compareTo(o2.getSSID());
        }
    }
}
Nir Alfasi
  • 53,191
  • 11
  • 86
  • 129
  • i really appreciate the help but i dont know, im starting to think the task is just very awkwardly posed. it literally says "to not have to implement quicksort twice, use a comparator that you give to the sorting method". but even with your suggestion i can only compare ssid, i cant somehow sort by mac in the same method. – banzai Apr 12 '15 at 17:52
  • 1
    @banzai got it. See the "update" section of the answer. – Nir Alfasi Apr 12 '15 at 18:44
0

Here's a sample Comparator I wrote to sort multi-dimensional arrays by their first element:

    private static class FirstItemComparator implements Comparator<int[]> {
        public int compare(int[] first, int[] second) {
            if (first[0] < second[0]) {
                return -1;
            } else if (first[0] == second[0]) {
                return 0;
            } else {
                return 1;
            }
        }
    }

    int[][] test = {{0,1},{4,8},{3,5}, {10,12}, {9,10}};
    Arrays.sort(input, new FirstItemComparator());
    // test is now {{0,1},{3,5},{4,8},{9,10},{10,12}}

Usually you will only write a comparator if you are going to pass it into a static method that compares two instances (passing a Comparator is essentially like passing a function in other languages). You can write different comparators to sort the same type of object in several different ways.

If you want to compare one instance to another instance, then you would implement the interface Comparable on the class itself (rather than create a new class, as I did). However, this imposes an ordering on the object, so you can't write three or four compareTo methods to sort objects in different ways.

egracer
  • 362
  • 3
  • 10
  • yeah, and what does Arrays.sort do with the new StartTimeComparator? That's what I don't get – banzai Apr 12 '15 at 17:15
  • 1
    It performs a sorting algorithm (probably a version of quick sort), but uses the compare method to determine the order of the one dimensional arrays inside of my two dimensional array. So instead of evaluating `if(item1 < item2)`, the sort now uses `if(theComparator.compare(item1, item2) < 0)`. – egracer Apr 12 '15 at 17:23