Quicksort java,中位数为前3个元素

时间:2016-04-06 04:25:58

标签: java quicksort median

我无法快速上班。我的家庭作业要求我将枢轴作为前3个元素的中位数,或者如果列表是<当我这样做时,排序会崩溃,一些元素会被其他元素覆盖。我不确定我缺少什么,但这里是代码:

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
    }
} 

当我更换问题开始的第3行时。

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

以下是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);
}

我不确定从哪里开始,我得到它的唯一方法是getPivot方法每次返回第一个元素,但它没有任何意义。有人能指出我正确的方向吗?谢谢。

1 个答案:

答案 0 :(得分:1)

在您返回之前,当交换将枢轴放在列表中间时,您错误地认为枢轴始终位于第一个位置。因此,您可能会丢失列表第一个位置的值,而是获取透视值的副本。您需要记住您找到枢轴的索引,并使用该索引而不是第一个索引进行交换。

还有另一个问题。将low变量初始化为first + 1时,您还假设枢轴位于第一个位置。你不应该在那里加1。否则,您可能在第一个位置最终得到一个大于数值的值。