Java 中位数为3的快速排序中的逻辑错误

Java 中位数为3的快速排序中的逻辑错误,java,quicksort,median,Java,Quicksort,Median,指令是编辑快速排序程序,以选择三个中间值作为轴心,而不是数组的第一个值 为此,我对代码进行了如下编辑: public class medianOf3 { //Main method and test array public static void main(String[] args) { int[] list = {2, 3, 2, 5, 6, 1, -2, 3, 14, 12}; quickSort(li

指令是编辑快速排序程序,以选择三个中间值作为轴心,而不是数组的第一个值

为此,我对代码进行了如下编辑:

public class medianOf3 {

        //Main method and test array 
        public static void main(String[] args) {

            int[] list = {2, 3, 2, 5, 6, 1, -2, 3, 14, 12};
            quickSort(list);
            for (int i = 0; i < list.length; i++)
                System.out.print(list[i] + " ");
            System.out.println();
        }

        public static void quickSort(int[] list) {
            quickSort(list, 0, list.length - 1);
        }
        //The quicksort method 
        public static void quickSort(int[] list, int first, int last) {
            if (last > first) {
                int pivotIndex = partition(list, first, last);
                quickSort(list, first, pivotIndex - 1);
                quickSort(list, pivotIndex + 1, last);
            }
        }

       // Returns the median of three integers 
        public static int median(int first, int middle, int last) {
            return Math.max(Math.min(first, middle), Math.min(Math.max(first, middle), last));
        }

        //returns the index of a value 
        public static int  findIndex (int[] list, int t) { 
            if (list == null) return -1;
            int len = list.length;
            int i = 0;
            while (i < len) {
                if (list[i] == t) return i;
                else i=i+1;
            }
            return -1;
        }

    public static int partition(int[] list, int first, int last) {

        int middle = ((last-first) / 2)+first;    
        int pivot = median(list[first], list[middle], list[last]); // selecting the median of three (of the first, middle and last value) as the pivot
        int low = first +1; // Index for forward search
        int high = last; // Index for backward search
        int index = findIndex(list, pivot );

        int swap = list[index];
        list[index] = list[0];
        list[0] = swap;

        while (high > low) {

            // Search forward from left
            while (low <= high && list[low] <= pivot)
            low++;
            // Search backward from right
            while (low <= high && list[high] > pivot)
            high--;
            // Swap two elements in the list
                if (high > low) {
                int temp = list[high];
                list[high] = list[low];
                list[low] = temp;
                }
            }

        while (high > first && list[high] >= pivot)
        high--;

        // Swap pivot with list[high]

        if (pivot > list[high]) {
            list[first] = list[high];
            list[high] = pivot;
            return high;
        } else { return first;}
        }  

}
分区方法的第行,是使用调试器发生错误的位置。我觉得这很可能是一个逻辑错误,但我不确定在这一点上到底出了什么问题

感谢所有反馈

我建议将其作为解决方案(基于您的代码,几乎没有更改):

publicstaticvoidmain(字符串[]args){
列表=数组.asList(2,3,2,5,6,1,-2,3,14,12);
快速排序(list,0,list.size()-1);
系统输出打印项次(列表);
}
私有静态void快速排序(列表、int first、int last){
如果(最后一个-第一个>0){
int pivot=pivot(列表、第一个、最后一个);
int index=分区(列表、第一个、最后一个、枢轴);
快速排序(列表,第一,索引-1);
快速排序(列表,索引+1,最后一个);
}
}
私有静态int-pivot(列表,int-first,int-last){
返回((最后一个-第一个)/2)+第一个;
}
私有静态int分区(列表、int-first、int-last、int-pivot){
集合.交换(列表、最后一个、透视);
int j=第一;
for(int i=first;iif(list.get(i)具有单个函数和堆栈溢出预防的替代示例(最坏情况下的时间复杂度仍然是O(n^2))。在该示例中,通过对[lo,md,hi]进行排序来执行中位数3,其中md=(lo+hi)/2,它采用3个if/swap

    @SuppressWarnings("empty-statement")
    public static void qsort(int[] a, int lo, int hi)
    {
        while(lo < hi){
            int  md = lo+(hi-lo)/2;
            int  ll = lo-1;
            int  hh = hi+1;
            int t;
            if(a[lo] >  a[hi]){         // median of 3
                t     = a[lo];
                a[lo] = a[hi];
                a[hi] = t;
            }
            if(a[lo] >  a[md]){
                t     = a[lo];
                a[lo] = a[md];
                a[md] = t;
            }
            if(a[md] >  a[hi]){
                t     = a[md];
                a[md] = a[hi];
                a[hi] = t;
            }
            int p = a[md];
            while(true){                // partition
                while(a[++ll] < p);
                while(a[--hh] > p);
                if(ll >= hh)
                    break;
                t     = a[ll];
                a[ll] = a[hh];
                a[hh] = t;
            }
            ll = hh++;
            // recurse on smaller part, loop on larger part
            if((ll - lo) <= (hi - hh)){
                qsort(a, lo, ll);
                lo = hh;
            } else {
                qsort(a, hh, hi);
                hi = ll;
            }
        }
    }
@SuppressWarnings(“空语句”)
公共静态无效qsort(int[]a,int lo,int hi)
{
while(loa[hi]){//中值为3
t=a[lo];
a[lo]=a[hi];
a[hi]=t;
}
如果(a[lo]>a[md]){
t=a[lo];
a[lo]=a[md];
a[md]=t;
}
如果(a[md]>a[hi]){
t=a[md];
a[md]=a[hi];
a[hi]=t;
}
int p=a[md];
while(true){//partition
而(a[++ll]p);
如果(ll>=hh)
打破
t=a[ll];
a[ll]=a[hh];
a[hh]=t;
}
ll=hh++;
//小部分递归,大部分循环

如果((ll-lo)再次查看此项,代码中的pivot方法是否不简单地使用中位数作为轴心,而不是中位数3(第一个、中间和最后一个条目的中位数)?确切地说,它使用中间值作为轴。轴需要是三个值的中间值,即未排序数组中第一个值、中间值和最后一个值的中间值。
public static void main(String[] args) {
    List<Integer> list = Arrays.asList(2, 3, 2, 5, 6, 1, -2, 3, 14, 12);
    quickSort(list, 0, list.size() - 1);
    System.out.println(list);
}

private static void quickSort(List<Integer> list, int first, int last) {
    if (last - first > 0) {
        int pivot = pivot(list, first, last);
        int index = partition(list, first, last, pivot);
        quickSort(list, first, index - 1);
        quickSort(list, index + 1, last);
    }
}

private static int pivot(List<Integer> list, int first, int last) {
    return ((last - first) / 2) + first;
}

private static int partition(List<Integer> list, int first, int last, int pivot) {
    Collections.swap(list, last, pivot);
    int j = first;
    for (int i = first; i < last; i++) {
        if (list.get(i) <= list.get(last)) {
            Collections.swap(list, i, j);
            j++;
        }
    }
    Collections.swap(list, last, j);
    return j;
}
    @SuppressWarnings("empty-statement")
    public static void qsort(int[] a, int lo, int hi)
    {
        while(lo < hi){
            int  md = lo+(hi-lo)/2;
            int  ll = lo-1;
            int  hh = hi+1;
            int t;
            if(a[lo] >  a[hi]){         // median of 3
                t     = a[lo];
                a[lo] = a[hi];
                a[hi] = t;
            }
            if(a[lo] >  a[md]){
                t     = a[lo];
                a[lo] = a[md];
                a[md] = t;
            }
            if(a[md] >  a[hi]){
                t     = a[md];
                a[md] = a[hi];
                a[hi] = t;
            }
            int p = a[md];
            while(true){                // partition
                while(a[++ll] < p);
                while(a[--hh] > p);
                if(ll >= hh)
                    break;
                t     = a[ll];
                a[ll] = a[hh];
                a[hh] = t;
            }
            ll = hh++;
            // recurse on smaller part, loop on larger part
            if((ll - lo) <= (hi - hh)){
                qsort(a, lo, ll);
                lo = hh;
            } else {
                qsort(a, hh, hi);
                hi = ll;
            }
        }
    }