快速排序中使用的两个分区版本的区别
Difference of the two versions of partition used in quicksort
第一个很简单,只需从两边走,直到找到回归。
/*C++ version, [first, last), last needs --first to fetch the last element*/
/*returns the middle of partitioning result*/
int* partition( int *first, int *last, int pivot ) {
while (true) {
while (*first < pivot) ++first;
--last;//Don't edit this, it's true.
while (pivot < *last) --last;
if (!(first < last)) return first;
swap(*first, *last);
++first;
}
}
第二个(如"算法简介"所示)是:
int* partition( int a[], int n, int pivot ) {
bound = 0;
for ( i = 1; i != n; ++i )
if ( a[i] < pivot )
swap( &a[i], &a[++bound]);
swap(a, a + bound);
return a + bound;
}
第二个的不变量是"有界之前的所有元素都小于枢轴"。
问:这两个版本的优点和缺点是什么?
我先给出一个,第二个需要对迭代器(指针)进行++操作,因此它可以应用于某些ForwardIterator
,例如链表的迭代器。其他提示?
就这两种算法的基本思想而言,两者都是正确的。他们将进行相同数量的比较,但第二个将比第一个进行更多的掉期。
您可以通过逐步执行算法来查看它们,因为它们使用 5 作为透视对数组进行分区1 9 2 8 3 7 4 6 5
。当第一个算法交换两个数字时,它永远不会再次接触任何一个。第二种算法首先交换 9 和 2,然后交换 9 和 3,依此类推,进行多次交换以将 9 移动到其最终位置。
还有其他差异。如果我没有犯任何错误,这就是第一个算法对数组进行分区的方式:
1 9 2 8 3 7 4 6 5
f l
1 9 2 8 3 7 4 6 5 # swap 9,5
f l
1 5 2 8 3 7 4 6 9 # swap 8,4
f l
1 5 2 4 3 7 8 6 9 # return f = 5
l f
这是第二种算法对数组进行分区的方式:
1 9 2 8 3 7 4 6 5 # 1<5, swap 1,1
bi
1 9 2 8 3 7 4 6 5 # 9>5, no swap
bi
1 9 2 8 3 7 4 6 5 # 2<5, swap 9,2
b i
1 2 9 8 3 7 4 6 5 # 8>5, no swap
b i
1 2 9 8 3 7 4 6 5 # 3<5, swap 9,3
b i
1 2 3 8 9 7 4 6 5 # 7>5, no swap
b i
1 2 3 8 9 7 4 6 5 # 4<5, swap 8,4
b i
1 2 3 4 9 7 8 6 5 # 6>5, no swap
b i
1 2 3 4 9 7 8 6 5 # 5=5, exit loop, swap 9,5
b i
1 2 3 4 5 7 8 6 9 # return b = 4
b i
请注意它如何进行 5 次交换,而其他算法只有 2 次。它还将数组中的最后一项移动到中间数组。在这种情况下,最后一项恰好是枢轴,因此它是移动到中间的枢轴,但这不是一般情况。
相关文章:
- 如何在C++中从两个单独的for循环中添加两个数组
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 当在同一名称空间中有两个具有相同签名的函数时,会发生什么
- 如何返回一个类的两个对象相加的结果
- 如何在C++中将一个无符号的 int 转换为两个无符号的短裤?
- 如何将两个不同矢量的同一位置的两个元素组合在一起
- 两个字符串在 c++ 中不相等
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 两个文件使用彼此的功能-如何解决
- 为什么Mat类的两个对象可以在不重载运算符+的情况下添加
- 如何确保在使用基于布尔值的两个方法之一调用方法时避免分支预测错误
- 停止cmake target_link_libraries将插件中静态库的两个对象文件链接到静态库本身
- 将fold表达式与std::一起用于两个元组
- 如何在C++中比较两个char数组
- 给定两个偶数,求出它们之间所有偶数的平方和
- 比较两个大小不等的映射c++
- 是否存在用于按以下方式对两个范围进行排序和分区的标准算法?
- 在C++中以相同的方式同时对两个元素范围进行分区
- 快速排序中使用的两个分区版本的区别
- 这两个分区函数之间的区别