快排模板中比较值的选取问题
存在问题
快排模板中,
int mid = (l + r + 1) / 2
,q[mid]
与q[i]、q[j]
比较
int x = q[(l + r + 1) / 2]
,x
与q[i]、q[j]
比较
这两者看起来等价,但前者是错误的。
错误样例:
分析过程
数据:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|
49 | 59 | 88 | 37 | 98 | 97 | 68 | 54 | 31 | 3 |
i | j | mid | q[mid] | |
---|---|---|---|---|
初始 | 0 | 9 | 5 | 97 |
quick_sort(q, 0, 9)
i、j指针移动到i:4 j:9
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|
49 | 59 | 88 | 37 | 98 | ==97== | 68 | 54 | 31 | 3 |
交换->swap(q[4], q[9])
由于i小于j(i:4 j:9
),继续移动
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|
49 | 59 | 88 | 37 | 3 | ==97== | 68 | 54 | 31 | 98 |
i、j指针移动到i:5 j:8
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|
49 | 59 | 88 | 37 | 3 | ==97== | 68 | 54 | 31 | 98 |
交换->swap(q[5],q[8])
i:5 j:8
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|
49 | 59 | 88 | 37 | 3 | 31 | 68 | 54 | 97 | 98 |
到此就可以发现问题的所在了,由于mid = (l + r + 1) / 2
,所以比较的q[mid]
变成了31,,不是原来的97了。
结论
如果由
1 | void quick_sort(int q[], int l, int r) |
由上面的例子可以发现,q[mid]的值在动态变化,从97变成了31,这违背了快排的思想。
所以正确的做法应该是int x = q[(l + r + 1) / 2]
1 | void quick_sort(int q[], int l, int r) |
用一个变量保存下中间的值,然后每次比较,将小于它的放在左边,大于它的放在右边。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Torch's blog!