快速排序优化方案的否定
记得曾参考教材与几篇博客,最终写出自己的快速排序终极版。
详情可见 排序系列。
最终的版本大概是下面这个样子。
1 int Partition(int first, int end) { 2 //此处选择数列第一个记录作为基准 3 int tmp = r[first]; 4 while (first < end) { 5 while (first < end&&r[first] <= r[end])end--;//终点位置的记录满足大于基准记录,则终点位置前移 6 if (first < end) { 7 r[first] = r[end]; 8 first++;//基准位置交换后,r[first]=r[end]恒成立,故first++ 9 } 10 while (first < end&&r[first] <= r[end])first++;//起点位置的记录满足小于基准记录,则起点位置后移 11 if (first < end) { 12 r[end] = r[first]; 13 end--;//基准位置交换后,r[first]=r[end]恒成立,故end-- 14 } 15 //当取数列最后一个记录作为基准时,上面两个while循环交换顺序 16 } 17 r[end] = tmp; 18 return end;//循环退出时,必定有first=end=partition 19 }
但是今天一个题目(输出前k大的数)偶然间暴露了它的错误性。
题目随意给了下面这样一个整数序列示例:
4 5 6 9 8 7 1 2 3 0
当时就想拿着快排在纸上试一下(反正演算量也不大(▽))
最后结果真是amazing啊!如下:
7 8 9 4 6 5 1 2 3 0
显然end为4,但是按降序排列end应为6。
这里甚至都不满足基准左边全部大于右边。
所以相当于无意间发现这是一种错误的快排编码方式。
以后还是老老实实swap吧!(╹▽╹)