繁体   English   中英

在java中解决我的快速排序算法?

[英]trouble-shooting my quicksort algorithm in java?

在解决我的quicksort算法方法时出现问题,这个问题突然出现了;

考虑这个单独打印数组元素的简单示例:

public static void print1(int[] arr, int start, int end){
        for (int k = start; k<end;k++){
            System.out.println(arr[k]);
        }
    }
    public static void print2(int[] arr, int start, int end){
        for (int k=start; k<=end;k++){
            System.out.println(arr[k]);
        }
    }

总的来说,如果我打电话:

public static void main(String[] args) {
        int[] data2 = new int[]{10,11,9,7,5};
       print1(data2,0,data2.length);
       System.out.println("___________");
       print2(data2,0,data2.length-1);
    }

两者都打印相同的内容,这是好的和好的; (注意,我将data2.lengthdata2.length-1作为参数传递给我的print1print2方法,并且每个方法中的for-loop相应地改变)

现在出现了快速排序制度的问题:考虑以下代码:

public static void quickSort2(int[] arr, int i, int j){
        if (i<j){
            int part =partition(arr, i, j);
            quickSort2(arr, i, part-1);
            quickSort2(arr, part+1, j); 
        }
    }

public static int partition(int[] arr, int start, int end){
        int pivot = arr[start];
        int i = start;
        for (int j = start+1;j<=end;j++){ // ******
            if (arr[j]<pivot){
                    i++;
                    int temp=arr[i];
                    arr[i]=arr[j];
                    arr[j]=temp;
            }
        }
        arr[start]=arr[i];
        arr[i]=pivot;
        return i;
    }

在主;

public static void main(String[] args) {
       //int[] data = new int[]{5,10,1,9,4,4,8,3,6,2,7,4};
        int[] data = new int[]{3,4,1,2};
        int[] data2 = new int[]{10,11,9,7,5};
       System.out.print("Unsorted array data ");
       display(data);
       System.out.print("\nUnsorted array data2 :");
       display(data2);
       quickSort2(data, 0, data.length-1);
       System.out.println("_____________");
       quickSort2(data2,0,data2.length-1);
       System.out.print("\nSorted array data: ");
       display(data);
       System.out.print("\nSorted array data2:");
       display(data2);
}

工作得很好,很好; now如果我将调用更改为quickSort(data, 0, data.length)并将for-loop行(在代码中标记为******* )更改for (int j = start+1;j<end;j++) ,我得到了完全不同的结果:即:前两个元素没有排序,但其余的元素被排序。 我明白了

Sorted array data: [2, 1, 3, 4]

Sorted array data2:[5, 9, 7, 10, 11]

我需要协助

快速浏览后,我认为有两个独立的错误 - 我在'main`中为每个quickSort2()调用发现了一个错误。 由于您尝试排序的数组的性质,每个都被触发。

错误1:在您的主要第9行,您致电:

quickSort(data, 0, data.length);

所以,这是当你尝试quickSort() {3,4,1,2}时。 在对quickSort2()的第一次递归调用时发生错误,其参数的确切调用是

quickSort2({2,1,3,4}, 0, 1);

然后使用相同的参数调用partition()

partition({2,1,3,4}, 0, 1);

这是发生错误的地方。 看看你的for-loop术语:

 for (int j = start+1; j< end;j++)

j将立即设置为1. End已等于1. 1 < 1为false,因此循环永远不会触发。 解决方案:在为j赋值时,只需删除+1。 你的循环将如下所示:

for (int j = start; j< end;j++) 

i == j的初始情况永远不会触发if-statement所以我认为应该没问题。

错误2:在主要的第11行,你打电话:

quickSort2(data2,0,data2.length-1);

发生最终误差在同一个地方,因为它在该第一故障没有-在partition()的第一递归调用期间quickSort2()这最终具有以下参数:

partition({5,9,7,10,11}, 0, 2);

永远不会触发for-loopif-statement ,因为5是数据透视表,9和7都是较大的。 因此, i返回零,这个数组的一半永远不会再次排序。 至于快速解决这个问题,我不能说有一个我能想到的。 你必须改变你的逻辑。

一些可能会帮助你的笔记/指针。

通常,Quicksort算法通常不会在数组中一直调用。 通常存在一种基本情况,其中排序切换到不同的算法。 例如,您只有5个对象可以对此调用进行排序。 那不是那么多,所以让我们切换到更简单的东西,比如插入排序。 尽管插入排序通常对大型集合的效率较低,但当您只需要重新排列5个或更少的对象时,这并不是什么大问题。

Quicksort实现通常也不会将集合中的第一个对象称为pivot。 这通常是一种糟糕的方法,如果您的列表已经排序或反向排序,该怎么办? 时间复杂度将非常平庸(O(N 2 ))。 相反,有一种称为“三个中位数”的方法,它不仅可以解决您的第二个错误,而且可以为您提供更好的时间复杂性。

在快速排序功能中调用第一个分区时,您还必须更改:

quickSort2(arr, i, part-1);

quickSort2(arr, i, part);

这是因为您没有使用最后一个索引(结束)。 因此,您的快速排序将不完整,因为您没有将最后一个元素放在枢轴之前,即使它的值低于数据透视表。

quickSort(data, 0, data.length-1);
//...
quickSort2(data2,0,data2.length-1);

我看到两个quickSort是不一样的,也许你有另一个名为quickSort的函数你忘了吗?或者只是写错了?

看看代码中添加了一些打印件并发现,经过修改后,在第二次运行你的pivot元素0时,显然是错误的。 我添加了一些数字作为未排序的数组数据:3 4 1 2 7 5 6

3 4 1 2 7 5 6

枢轴:2
2 1 3 4 7 5 6

pivot:0
2 1 3 4 7 5 6

2 1 3 4 7 5 6

2 1 3 4 7 5 6

枢轴:3
2 1 3 4 7 5 6

2 1 3 4 7 5 6

枢轴:6
2 1 3 4 6 5 7

枢轴:4
2 1 3 4 6 5 7

2 1 3 4 6 5 7

2 1 3 4 6 5 7

排序数组数据:2 1 3 4 6 5 7

package quicksort;

public class Quicksort {

public static void main(String[] args) {
        int[] data = new int[]{3,4,1,2,7,5,6};
       System.out.print("Unsorted array data:\n");
       display(data);
       quickSort2(data,0,data.length);
       System.out.print("\nSorted array data:\n");
       display(data);
}

public static void quickSort2(int[] arr, int i, int j){
    display(arr);
    if (i<j){
        int part =partition(arr, i, j);
        quickSort2(arr, i, part-1);
        quickSort2(arr, part+1, j); 
    }
}

public static int partition(int[] arr, int start, int end){
    int pivot = arr[start];
    //System.out.println(pivot);
    int i = start;
    int temp;
    for (int j = start;j<end;j++){ // ******
        if (arr[j]<pivot){
                i++;
                temp=arr[i];
                arr[i]=arr[j];
                arr[j]=temp;
        }
    }
    arr[start]=arr[i];
    arr[i]=pivot;
    System.out.println("pivot: "+i);
    return i;
}

public static void display(int[] data){
for(int i=0;i<data.length;i++){
    System.out.print(data[i]+" ");
}
System.out.println("\n");
}}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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