快速排序两种写法的注意点
1.自创写法(根据快速排序原理 ,使用while)
-
这里有一组hack数据就是数组中存在两个元素值相等的情况,此时backup[i]和backup[j]相等,此时交换之后如果不写i ++ , j ++ 就会造成i , j 指针在下一次循环中,仍然会卡在原来的位置,从而造成死循环。所以每两个元素交换完了之后一定要保证指针的移动。
-
由于上面这种写法,造成j所在的位置及左边都是小于等于backup[l]的元素,右边都是大于backup[l]的元素,但是backup[l]不一定在j的位置,所以下一次分治的时候还是需要将j这个位置纳入排序的
-
这里由于是先做while(而不是先做自增操作来保证第一个元素正常),所以不用设置初始值为i = l - 1 , j = r + 1
-
注意此时backup[i]与k不能取等,否则会死循环,因为只要有一个重复元素出现,就不会存在一个数左边都比他小,右边都比他大的情况,所以排序会错误,
快速排序的正统思想也是这个选出来的数的左边一定小于等于这个数,右边大于等于这个数
void quick_sort(int l , int r){
if(l >= r) return ;
printf("l : %d , r : %d\n" , l , r);
int k = backup[l];
int i = l , j = r;
printf("i : %d , j : %d\n" , i , j);
while(i < j){
printf("i : %d , j : %d\n" , i , j);
while(backup[i] < k) i ++;
while(backup[j] > k) j --;
if(i < j) swap(backup[i] , backup[j]) , i ++ , j --;
}
quick_sort(l , j);
quick_sort(j + 1 , r);
}
2.Y总写法
- 这里i取l - 1 , j 取r + 1也是配合后面的do while写法,因为do while不管三七二十一直接就加了,而我们为了保证首尾两个数被加,所以要i提前一格,j延后一格。
- 注意这里使用p[l]的话递归只能递归j,hack数据为[1 , 2],表现为死循环,使用p[r]的话只能递归i,对应的地方也要对称的改
void quick_sort(int p[] , int l , int r){
if(l >= r) return;
int i = l - 1;
int j = r + 1;
int x = p[l + rand() % (r - l + 1)];
while(i < j){
do i++; while(p[i] < x);
do j--; while(p[j] > x);
if(i < j) swap(p[i] , p[j]);
}
quick_sort(p , l , j);
quick_sort(p , j + 1 , r);
}
本文作者:带一把雨伞当剑
本文链接:https://www.cnblogs.com/oneArbor/p/18576326/howQuickSort
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步