Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/289.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.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
Python Bentley McIlroy三向分区_Python_Algorithm_Sorting_Partitioning_Quicksort - Fatal编程技术网

Python Bentley McIlroy三向分区

Python Bentley McIlroy三向分区,python,algorithm,sorting,partitioning,quicksort,Python,Algorithm,Sorting,Partitioning,Quicksort,下面是我编写的Hoare分区算法,它基于给定的轴对数组进行分区(在本例中,它是数组的第一个元素,是一个非常糟糕的选择!)。然而,Bentley McIlroy 3路分区at声称,当键数相等时,它可以提供更好的性能。有人能简要解释一下第9页上的代码实现了什么,以及为什么它比Hoare算法性能更好吗?还有一个问题,分区基于放置元素。如果多次出现的元素不是轴心呢 def hoare(arr,start,end): pivot = arr[start] i,j = start,end

下面是我编写的
Hoare
分区算法,它基于给定的轴对数组进行分区(在本例中,它是数组的第一个元素,是一个非常糟糕的选择!)。然而,Bentley McIlroy 3路分区at声称,当键数相等时,它可以提供更好的性能。有人能简要解释一下第9页上的代码实现了什么,以及为什么它比
Hoare
算法性能更好吗?还有一个问题,分区基于
放置元素。如果多次出现的元素不是轴心呢

def hoare(arr,start,end):
     pivot = arr[start]
     i,j = start,end
     while i < j:
        while i < j and arr[i] <= pivot:
            i += 1
        while j >= i and arr[j] > pivot:
            j -= 1
        if i < j:
            arr[i],arr[j] = arr[j],arr[i]
     arr[start],arr[j] = arr[j],arr[start]
     return j
def hoare(arr,start,end):
枢轴=arr[开始]
i、 j=开始,结束
而i枢轴时:
j-=1
如果i
我认为,第8页的图表很好地解释了第9页的代码:您首先进行分区,但也将等于轴的元素交换到向量的边缘,因此它最终是:

[equals-left] [lesses] [greaters] [equals-right]
然后将相等的元素交换回中心:

[lesses] [equals-left] [equals-right] [greaters]
然后递归排序
[lesses]
[greaters]

塞奇威克的假设是,数据集中有许多重复的元素。在这种情况下,重复轴是很常见的,如果是这样,您可以通过在任何一个快速排序递归中不包含轴的任何重复来获得一些好处,这样两个分区之和的大小将小于向量的大小,即轴的重复数(即使它本身)这减少了需要递归的元素数量,从而加快了递归速度

这样做的代价是每个元素额外进行一到两次比较,尽管这两次比较都只是以不同的成功条件重复先前的比较。如果比较比较复杂,您可能希望使用显式的三方比较函数,以便能够保存最后一次比较的结果(在Sedgwick代码中的while循环中)。如果轴没有重复,那么这正是额外的成本:那些额外的比较。如果轴重复,那么就有一个或两个额外的交换和两个或一个额外的比较(如果交换和比较,那么三个额外的操作需要相同的时间)对于每个重复的枢轴元素,加上每个其他元素的两个额外比较


这值得吗?我很怀疑,但如果塞奇威克说值得,那么你可能应该听他而不是我的话。

我认为,第9页上的代码在第8页的图表中解释得很好:你首先进行分区,但也将等于轴的元素交换到向量的边缘,因此它最终是:

[equals-left] [lesses] [greaters] [equals-right]
然后将相等的元素交换回中心:

[lesses] [equals-left] [equals-right] [greaters]
然后递归排序
[lesses]
[greaters]

Sedgwick的假设是数据集中有许多重复的元素。在这种情况下,重复pivot是很常见的,如果是这样的话,您可以通过不在任何快速排序递归中包含pivot的任何重复来获得一些好处,这样两个分区之和的大小将是less比向量的大小乘以轴的重复次数(即使它只是自身的重复次数),这减少了需要递归的元素数量,从而加快了递归速度

这样做的代价是每个元素额外进行一到两次比较,尽管这两次比较都只是以不同的成功条件重复先前的比较。如果比较比较复杂,您可能希望使用显式的三方比较函数,以便能够保存最后一次比较的结果(在Sedgwick代码中的while循环中)。如果轴没有重复,那么这正是额外的成本:那些额外的比较。如果轴重复,那么就有一个或两个额外的交换和两个或一个额外的比较(如果交换和比较,那么三个额外的操作需要相同的时间)对于每个重复的枢轴元素,加上每个其他元素的两个额外比较


这值得吗?我很怀疑,但如果塞奇威克说值得,那么你可能应该听他的而不是我的。

我发现基于N.Lumoto的想法实现3路分区是可能的,这稍微容易一些。(正如Jon Bentley在他的《编程珍珠》一书中提到的,Lumoto的方法很简单)

其思想是在扫描过程中保持不变,即在任何时候,小于轴的元素都放在最左边的部分,而等于轴的元素则放在该部分的旁边,大于轴的元素则放在最右边。其余部分是尚未检查的元素

这些部分由i、k和j限定。当我们检查一个元素时,如果它等于轴,我们只需前进到下一个元素,如果它小于轴,我们可以将它与“相等”部分上的第一个元素交换,这样不变量就可以恢复。否则,我们需要继续与大部分前面的最后一个元素交换离子

/*
 * Another 3-way partition ternery quick sort based on N. Lomuto's method.
 *   Invariant: ... less ... | ... equal ... | ... ? ... | greater |
 *                           i               k           j
 */
void qsort3(Key* xs, int l, int u) {
    int i, j, k; Key pivot;
    if (l < u - 1) {
        i = l; j = u; pivot = xs[l];
        for (k = l + 1; k < j; ++k) {
            while (pivot < xs[k]) { --j; swap(xs[j], xs[k]); }
            if (xs[k] < pivot) { swap(xs[i], xs[k]); ++i; }
        }
        qsort3(xs, l, i);
        qsort3(xs, j, u);
    }
}
/*
*另一种基于N.Lomuto方法的三向分区快速排序。
*不变量:…小于…|…等于…|…?…|更大|
*i k j
*/
无效qsort3(键*xs,整数l,整数u){
关键支点;
如果(l
我用100000个元素对这个程序进行了测试