交换排序之快排

快速排序

基本概念

分治法思想。
把一个未排序的元素作 主元 / 基准 / 枢轴(pivot,通常取首元素);根据主元将所有元素划分为两个子序列,一个子序列的元素均比主元大,另一个均比主元小;递归地用相同的方法对两个子序列排序;直至每个子序列均有一个元素 or 为空。

图示

  1. 第一轮

快排1快排2快排3快排4快排5
2. 第二、三轮
快排6
快排7

快排8

代码

//划分左右子表
int Partition(int A[],int low,int high){ //升序
	int pivot = A[low];		//选第一个元素为主元
	while( low < high){		//low为左指针,high为右指针,所指元素与主元比较大小
	  //左<右 且 右>主 => 右指针左移  —— 符合条件,仅动指针 
		while( low < high && A[high] >= pivot ) --high; 
		A[low] = A[high];	//if右<主, 将右指针所指元素赋给左端low所指位置
		//左<右 且 左<主 => 左指针右移 —— 符合条件,仅动指针
		while( low < high && A[low] <= pivot ) ++low; 
		A[high] = A[low];	//if左>主, 将左指针所指元素赋给右端high所指位置
	}
	A[low] = pivot;	//两指针指向同一位置,放入主元
	return low;	//返回主元所在位置
}
//快排
void QuickSort(int A[],int low,int high){
	if(low < high){    // 递归跳出的条件
		int pivotpos = Partition(A,low,high);  //划分左右子表
		QuickSort(A,low,pivotpos-1);    //划分该趟主元的左子表
		QuickSort(A,pivotpos+1,high);    //划分该趟主元的右子表
	}
}

效率

  • 时间复杂度 = 关键代码执行次数 = O(n*递归层数)
    最好:O(nlog₂n)
    最坏:O(n²) —— 可优化,尽量选可以把数据中分的主元
  • 空间复杂度 = O(递归层数)
    最好:O(log₂n)
    最坏:O(n)
  • 递归层数 = 调用栈的高度 (可看做 log₂n)
    在这里插入图片描述
    在这里插入图片描述
算法分析
  • 不稳定
  • 原地排序,但借助递归工作栈(空间复杂度来源于此,不是O(1))
  • 数组,快排 于 插入排序
  • 初始大多有序 或 所选主元划分的左右子表不均匀(如: _ O _ _ _ _ _ _ ),均会导致性能变差(递归栈深度增加)
  • ⼀次划分可确定⼀个元素的最终位置(主元),⼀趟排序至少可确定1个元素的最终位置(1趟maybe确定多个)

听说快排还有稳定版本的,目前没空深究,后面抽空研究研究,要是可行,我再补上
上述图片取自王道课件。内容用于自学,如有错误,还请各位指正!

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

俺要工作俺想工作

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值