gpt4 book ai didi

c++ - 快速排序中使用的两个分区版本的区别

转载 作者:搜寻专家 更新时间:2023-10-31 01:47:42 25 4
gpt4 key购买 nike

第一个很简单,从两边走,直到找到一个返回。

/*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++ - 快速排序中使用的两个分区版本的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18889110/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com