【问题标题】:Quicksort not sorting快速排序不排序
【发布时间】:2010-02-23 08:02:28
【问题描述】:

所以我正在尝试创建一个快速排序方法,但是,它没有正确排序。这是我的输入和输出
原始数组:
80.0 10.0 50.0 70.0 60.0 90.0 20.0 30.0 40.0 0.0
排序数组:
0.0 30.0 20.0 80.0 40.0 60.0 70.0 10.0 90.0 50.0

我尝试将 for 循环更改为 for(int i = left; i < right; i++)
但现在的输出是:
0.0 20.0 30.0 40.0 80.0 10.0 60.0 90.0 70.0 50.0

    public static void sort(double[] a)
    {
        quickSort(a, 0, a.length-1);
    }

    public static void quickSort(double [] a, int left, int right)
    {
        if (left < right)
        {
            int pivotIndex = (left+right)/2;
            int pos = partition(a,left,right,pivotIndex);
            quickSort(a,left,pos-1);
            quickSort(a,pos+1,right);
        }
    }

    private static int partition(double [] a, int left,int right,int pivotIndex)
    {
        double temp = a[pivotIndex];
        a[pivotIndex] = a[right];
        a[right] = temp;
        int pos = left;//represents boundary between small and large elements
        for(int i = left; i < right-1; i++)
        {
            if (a[i] <= a[pivotIndex])
            {
                double temp2 = a[i];
                a[i] = a[pos];
                a[pos] = temp2;
                pos++;
            }
        }
        double temp3 = a[pivotIndex];
        a[pivotIndex] = a[pos];
        a[pos] = temp3;
        return pos;
    }

【问题讨论】:

    标签: java quicksort


    【解决方案1】:

    这就是你想要做的:

    private static void swap(double[] a, int i, int j) {
        double t = a[i];
        a[i] = a[j];
        a[j] = t;
    }
    
    private static int partition(double [] a, int left,int right,int pivotIndex)
    {
        swap(a, pivotIndex, right);
        int pos = left;//represents boundary between small and large elements
        for(int i = left; i < right; i++)
        {
            if (a[i] < a[right])
            {
                swap(a, i, pos);
                pos++;
            }
        }
        swap(a, right, pos);
        return pos;
    }
    

    我通过一个帮助器swap 方法使代码更清晰。您在原始代码中有 3 个错误:

    • 循环边界上的一次性错误
    • 您使用错误的索引来获取循环中的枢轴元素
    • 您在循环后交换了错误索引处的元素

    【讨论】:

    • 将pivotIndex作为参数传递是没有用的,在分区内计算它会更有效(顺便避免所有交换的东西)......无论如何分区都已经返回了枢轴位置。
    • 我不想过多地更改他的原始代码;我只是想纠正我看到的任何错误。重构交换是为了清晰,而不是效率。
    【解决方案2】:

    改变

    for(int i = left; i < right-1; i++)
    

    for(int i = left; i < right; i++)
    

    【讨论】:

    • 那没用,我现在的输出是:0.0 20.0 30.0 40.0 80.0 10.0 60.0 90.0 70.0 50.0
    • 最后一次swap必须在pos和right之间,而不是pos和pivotIndex之间
    • 在循环内,主元值在a[right],而不是a[pivotIndex]