Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/353.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,我已经在java中的ArrayList上实现了一个通用的快速排序,但是它只有在我选择pivot作为数组中最右边的项时才起作用。我尝试选择中间项和随机项,这两个项都只返回部分排序的ArrayList。我特别想知道为什么quickSortRecursive中的两个注释掉的pivot选择方法会导致ArrayList无法完全排序。感谢您的帮助 public static <T> void quicksort(ArrayList<T> a, Comparator<? supe

我已经在java中的ArrayList上实现了一个通用的快速排序,但是它只有在我选择pivot作为数组中最右边的项时才起作用。我尝试选择中间项和随机项,这两个项都只返回部分排序的ArrayList。我特别想知道为什么quickSortRecursive中的两个注释掉的pivot选择方法会导致ArrayList无法完全排序。感谢您的帮助

public static <T> void quicksort(ArrayList<T> a, Comparator<? super T> cmp){
    int left = 0;
    int right = a.size()-1;
    quickSortRecursive(left, right,a, cmp);
}

private static <T> void quickSortRecursive(int left,int right, ArrayList<T> a,  Comparator<? super T> cmp){

    if(left >= right){
        return;
    }
    T pivot = a.get(right);
    //T pivot = a.get(rand.nextInt(a.size()-1));
    //T pivot = a.get((left+right)/2);

    int partition = partition(left, right, pivot, a, cmp);
    quickSortRecursive(0, partition-1,a,cmp);
    quickSortRecursive(partition+1, right,a,cmp);

}


private static <T> int partition(int left,int right,T pivot, ArrayList <T> a,Comparator<? super T> cmp){

    int leftCursor = left-1;
    int rightCursor = right;

    while(leftCursor < rightCursor){
        while(cmp.compare(a.get(++leftCursor), pivot)<0);
        while(rightCursor > 0 && (cmp.compare(a.get(--rightCursor), pivot)>0));
        if(leftCursor >= rightCursor){
            break;
        }
        else{
            swap(leftCursor, rightCursor, a);
        }
    }
    swap(leftCursor, right, a);
    return leftCursor;
}


public static <T> void swap(int left,int right, ArrayList<T> a){
    T temp = a.get(left);
    a.set(left, a.get(right));
    a.set(right, temp);
}

publicstaticvoidquicksort(arraylista,Comparator)所以您几乎可以做到这一点,但是我可以看出这段代码有一些地方是错误的:

  • 通常用于声明未知类型的函数或创建泛型函数,此处无需使用该函数。您只需使用您选择的任何类型的数组,即
    int[]data
    ,即可替代arrayList
  • Pivot是在数据范围内任意选择的索引,尽管通常使用
    (左+右)/2
    它的类型很可能是
    int
  • 您有两种方法
    quickSortRecursive
    partition
    。但是,这些方法属于一个函数,因为您需要为要排序的每个数据子集计算枢轴。此方法不需要返回类型,所以只需在方法声明中使用
    void
成功地将数据划分为子集后,需要选择一个轴,将该轴与该子集中的最后一项交换

然后,您需要循环遍历数据子集,并将每个数据项与枢轴值(我们刚刚交换它时,它位于数据子集的末尾)进行比较 交换物品

在交换所有项之后,有必要通过将数据与最后一个要排序的项交换,将枢轴索引中的数据放回原处

只有这样,才能对其余数据递归调用函数:

递归调用函数时:

quickSortRecursive(0, partition-1,a,cmp);
quickSortRecursive(partition+1, right,a,cmp);
您应该将left而不是0传递到函数中,因为传递0将导致始终从数据最左侧排序


希望这能有所帮助。

所以您就快到了,但是我发现这段代码有一些地方不对劲:

  • 通常用于声明未知类型的函数或创建泛型函数,此处无需使用该函数。您只需使用您选择的任何类型的数组,即
    int[]data
    ,即可替代arrayList
  • Pivot是在数据范围内任意选择的索引,尽管通常使用
    (左+右)/2
    它的类型很可能是
    int
  • 您有两种方法
    quickSortRecursive
    partition
    。但是,这些方法属于一个函数,因为您需要为要排序的每个数据子集计算枢轴。此方法不需要返回类型,所以只需在方法声明中使用
    void
成功地将数据划分为子集后,需要选择一个轴,将该轴与该子集中的最后一项交换

然后,您需要循环遍历数据子集,并将每个数据项与枢轴值(我们刚刚交换它时,它位于数据子集的末尾)进行比较 交换物品

在交换所有项之后,有必要通过将数据与最后一个要排序的项交换,将枢轴索引中的数据放回原处

只有这样,才能对其余数据递归调用函数:

递归调用函数时:

quickSortRecursive(0, partition-1,a,cmp);
quickSortRecursive(partition+1, right,a,cmp);
您应该将left而不是0传递到函数中,因为传递0将导致始终从数据最左侧排序

希望这能有所帮助。

--rightCursor
首先递减变量,然后使用它(已经递减)

因此,由于
right=a.size()-1;
最右边的元素将被忽略(轴元素除外,轴元素会被比较)。

--rightCursor
首先递减变量,然后使用它(已经递减)


因此,由于
right=a.size()-1;
最右边的元素将被忽略(轴元素除外,轴元素无论如何都会被比较).

为什么不将选定元素与最右边的元素交换?随机性属性不取决于元素的数组最终位置。非常好的算法书籍就是这样进行的。您应该谈谈您自己为诊断问题所做的工作。为什么不将选定元素与最右边的元素交换?随机数mness属性不依赖于元素的数组最终位置。非常好的算法书籍就是这样进行的。您应该谈谈您自己为诊断问题所做的工作。