快速排序两种写法的注意点

快速排序两种写法的注意点

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);
 }

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值