快速排序C++(非随机快排)

快速排序与归并排序一样利用了分治思想,将序列分为两个总体有序子序列(即子序列A中所有元素都小于子序列B),再对子序列进行排序最后合并。

#include<iostream>

using namespace std;

void QuickSortJy(int a[],int l,int r){       //l,r为递归中当前序列的左右边界
  if(l>=r) return;     //递归结束条件:子序列只剩下一个元素,无需排序
  
  //对子序列排序的具体思想为:取一个key值将序列分为小于key和大于key的两个子序列,然后重复以上步骤,即对两个子序列递归排序
 
  int key=a[l];        //普通快速排序中key值一般为左右端点
  int ll=l,rr=r;     //ll为左游历指针,rr为右游历指针
  while(ll<rr){       //当ll与rr相遇之时,则左右序列已排序好


     //右边找小于key
     while(a[rr]>key&&rr>ll) rr--;   //注意rr>ll,若为rr>=ll,若ll未移动则会越界 


     //左边找大于key  
     while(a[ll]<=key&&ll<rr) ll++;               //注意<=,否则出错


     //此时ll为左子序列中大于key的元素,rr为右子序列中小于key的元素,则需要交换

     int temp=a[rr];
     a[rr]=a[ll];
     a[ll]=temp;
  }
  
  //此时ll==rr且以此为分界点的左右子序列已经排好序,要先把Key值放到该位置,即将进入递归
  a[l]=a[ll];     //!!!!注意把相遇位置的数字放回选择的端点处 
                  //此时相遇处分析:无论是ll走过去找rr还是rr走过去找ll,相遇点的数字都小于key
  a[ll]=key;
  QuickSortJy(a,l,ll-1);
  QuickSortJy(a,ll+1,r);

}

int main(){
  int n;
  cin>>n;
  int a[n];
  for(int i=0;i<n;i++) cin>>a[i];
  QuickSortJy(a,0,n-1);
  for(int i=0;i<n;i++) cout<<a[i]<<' ';
 
}

时间复杂度分析:

最坏情况:每次取的key都是最小或者最大数字,则递归下来的子序列可以看作一个只有左子树或者只有右子树的二叉树,共有n层,每一层指针都要遍历n次,所以时间复杂度为(n2)

若为最好情况:每次取得key值都是中位数,则每次将序列分为两个大小几乎相等的子序列,可以看作生成了一个完全二叉树,即有logn层,每一层遍历n/2,n/4,n/8...次,所以总时间复杂度为O(nlogn)

所以快速排序的时间复杂度在nlogn到n2之间

  • 10
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值