简体   繁体   中英

Quicksort java with median of first 3 elements

I am having trouble getting a quicksort to work. My homework assignment requires that I make the pivot be the median of the first 3 elements, or the first element if the list is < 3. When I do that the sort falls apart and some elements are overwritten with other elements. I'm not sure what I'm missing, but here is the code:

private static <E extends Comparable<E>> int partition(ArrayList<E> list, int first, int last) {
    ArrayList<E> subList = new ArrayList<E>(list.subList(first, last));
    E pivot = list.get(0);

    int low = first + 1; // Index for forward search
    int high = last; // Index for backward search

    if(list.get(0).getClass().equals(String.class)){
        while (high > low) {
            // Search forward from left
            while (low <= high && list.get(low).toString().compareToIgnoreCase(pivot.toString()) <= 0)
                low++;

            // Search backward from right
            while (low <= high && list.get(high).toString().compareToIgnoreCase(pivot.toString()) > 0)
                high--;

            // Swap two elements in the list
            if (high > low) {
                E temp = list.get(high);
                list.set(high, list.get(low));
                list.set(low, temp);
            }
        }

        while (high > first && list.get(high).toString().compareToIgnoreCase(pivot.toString()) >= 0)
            high--;

        // Swap pivot with list.get(high)
        if (pivot.toString().compareToIgnoreCase(list.get(high).toString()) > 0) {
            list.set(first, list.get(high));
            list.set(high, pivot);
            return high;
        }
        else {
            return first;
        }
    }else{
        //same code, but doesn't convert toString for comparisons
    }
} 

When I replace line 3 that's where the problems begin.

//E pivot = list.get(0);
//change to
E pivot = getPivot(subList);

Here is the code for get pivot:

private static <E extends Comparable<E>> E getPivot(ArrayList<E> list){
    if(list.size() < 3){
        return list.get(0);
    }else{
        //sorts ignoring case if the type of data in the list is strings
        if(list.get(0).getClass().equals(String.class)){
            if(list.get(0).toString().compareToIgnoreCase(list.get(1).toString()) > 0){
                if(list.get(0).toString().compareToIgnoreCase(list.get(2).toString()) <= 0){
                    return list.get(0);
                }else if(list.get(1).toString().compareToIgnoreCase(list.get(2).toString()) > 0){
                    return list.get(1);
                }
            }else if(list.get(0).toString().compareToIgnoreCase(list.get(1).toString()) <= 0){
                if(list.get(0).toString().compareToIgnoreCase(list.get(2).toString()) > 0){
                    return list.get(0);
                }else if(list.get(1).toString().compareToIgnoreCase(list.get(2).toString()) <= 0){
                    return list.get(1);
                }
            }
        }else{
            //same code, but doesn't convert toString for comparisons
        }
    }
    return list.get(2);
}

I am not really sure where to go from here, the only way I get it to work is if the getPivot method returns the first element each time, but then it serves no purpose. Can someone point me in the right direction? Thank you.

Right before you return, when swapping to put the pivot in the middle of the list, you are incorrectly assuming that that the pivot is always in the first position. Because of this, you may lose the value which was in the first position of the list, and get a duplicate of the pivot value instead. You need to remember at which index you found the pivot, and swap with that index instead of the first index.

There is also another issue. When you initialize the low variable to first + 1 , you are also assuming that the pivot is in the first position. You should not add 1 there. Otherwise you might end up with a value larger than pivot in the first position.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM