Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用重复值进行快速排序_Java_Quicksort - Fatal编程技术网

Java 使用重复值进行快速排序

Java 使用重复值进行快速排序,java,quicksort,Java,Quicksort,我已经实现了以下代码,但它似乎不适用于数组具有重复值的情况 private int partition(Integer[] arr,int left, int right) { int i = left; int j = right; int pivot = arr[left]; while(true) { while(arr[i] <pivot) i++; while(arr[j] > pivot) j

我已经实现了以下代码,但它似乎不适用于数组具有重复值的情况

 private int partition(Integer[] arr,int left, int right)
 {
    int i = left;
    int j = right;
    int pivot = arr[left];

    while(true) 
    {
        while(arr[i] <pivot) i++;
        while(arr[j] > pivot) j--;

        if(i < j)
        {
            print(arr);
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
        else return j; 
    }
}


public void quickSort(Integer[] arr, int left,int right)
{
    print(arr);
    if(left >= right) return;

    int index = partition(arr,left,right);

    quickSort(arr,left,index-1);
    quickSort(arr,index+1,right);
}
private int分区(整数[]arr,int left,int right)
{
int i=左;
int j=右;
int pivot=arr[左];
while(true)
{
而(arr[i]pivot)j--;
if(i=右)返回;
int index=分区(arr、左、右);
快速排序(arr,左,索引-1);
快速排序(arr,索引+1,右);
}
我发现了一个稍微不同的实现,在这种情况下效果非常好,但我不明白为什么。任何帮助都将不胜感激

    private int partition(Integer[] arr, int left, int right)
    {
    int i = left-1;
    int j = right+1;
    int pivot = arr[left];


    while(true) 
    {

        while(arr[++i] < pivot) ;
        while(arr[--j] > pivot) ;

        if(i < j)
        {
            print(arr);
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
        else return j; 
     }
     }

    public void quickSort(Integer[] arr, int left,int right)
    {
    print(arr);
    if(left >= right) return;

    int index = partition(arr,left,right);

    quickSort(arr,left,index);
    quickSort(arr,index+1,right);
    }
private int分区(整数[]arr,int left,int right)
{
int i=左-1;
int j=右+1;
int pivot=arr[左];
while(true)
{
while(arr[++i]pivot);
if(i=右)返回;
int index=分区(arr、左、右);
快速排序(arr、左、索引);
快速排序(arr,索引+1,右);
}
这是您的代码:

    while(arr[i] <pivot) i++;
    while(arr[j] > pivot) j--;
while(arr[i]pivot)j--;
以下是它们代码中的不同之处:

    while(arr[++i] < pivot) ;
    while(arr[--j] > pivot) ;
while(arr[++i]pivot);
请注意,它们使用了预递增/递减运算符++i和--j。 因此,while中的第一个检查将在检查之前递增或递减

这相当于:

do{ i++; }while(arr[i] < pivot);
do{ j--; }while(arr[j] > pivot);
do{i++;}while(arr[i]pivot);

关键是,在第一次比较之前,需要增加i和减少j。

1.选择一个元素作为轴心

2.将小于轴的所有图元向左移动,将大于轴的所有图元向右移动

3.将上述步骤应用于两个零件

下面的方法实现了快速排序。它定义了一种对子数组进行排序的递归方法,还定义了一种将数组分为两部分的方法

public static void quickSort(int[] data, int first, int last)
      {
        if (first >= last)return;
        int pivot = partition(data, first, last);
        quickSort(data, first, pivot - 1); // sort the left part
        quickSort(data, pivot + 1, last); // sort the right part
      }
分区过程包括拾取轴并围绕轴移动元素。一个简单的程序如下:

1,分配一个包含分区结果的新临时数组

2.拾取第一个元素作为枢轴

3.从第二个元素开始扫描数组,将每个元素与枢轴进行比较,如果小于或等于枢轴,则将其放在临时数组的左端,否则将其放在右端

4.最后将临时数组的结果复制回原始数组

public static int partition(int[] data, int first, int last)
 {
int[] temp = new int[last - first + 1];
int pivot = data[first];
int i = 0, j = last - first, k;

for (k = first + 1; k <= last; k++)
{
    if (data[k] <= pivot)
        temp[i++] = data[k];
    else
        temp[j--] = data[k];
}
temp[i] = data[first];

// Copy data back into original array
for (k = first; k <= last; k++)
    data[k] = temp[k - first];
return first + i;
  }
公共静态int分区(int[]数据,int-first,int-last)
{
int[]temp=new int[last-first+1];
int pivot=数据[第一];
int i=0,j=last-first,k;

对于(k=first+1;k它是如何工作的?根据您的代码应该对重复值排序的是什么?这不是唯一的区别。在第二个代码中,他更改了Quicksort递归调用的初始化以及i和j的初始化。但这不是我的问题。我的问题是,为什么第二个可以处理重复值。谢谢你的解释。我想我已经理解了快速排序,但我的问题更多的是关于代码的差异,这使得第二个代码能够正确地处理具有重复项的数组,而我的代码不能工作。
public static int partition(int[] data, int first, int last)
 {
int pivot = data[first];
int left = first, right = last;

while (left < right)
{
    // Find an element bigger than the pivot from the left
    while (data[left] <= pivot && left < right)
        left++;
    // Find an element smaller than the pivot from the right
    while (data[right] > pivot)
        right--;
    // Swap the two elements found
    if (left < right)
        swap(data, left, right);
}

// move the pivot element to the middle
swap (data, first, right);
return right; }