快速排序
给定一个序列:
进行快速排序
主要思想
从序列中,任选一个记录k作为轴值pivot选择策略:第一个元素最后一个元素中间元素随机选择将剩余的元素,分割成左子序列L和右子序列RL中所有元素都k,R中所有元素都k对L和R递归进行快排,直到子序列中有0个或者1个元素,退出图解
初始数组:选定47为轴值pivot
pivot与最后一个值29进行交换()
接下来,以pivot=47为界,分成左子序列L和右子序列R比47大的都放在右边,比47小的都放在左边(用的交换)
遍历数组
两个指针left和right当left!=right的时候如果left和right未相遇。把right的值赋给left对应的值arr[left]=arr[right]right指针停止移动,轮到left移动如果left和right未相遇,把left的值赋给right对应的值arr[right]=arr[left]left指针停止移动,轮到right移动若arr[left]的,小于等于pivot,且leftright的时候,left右移当arr[right]的值,大于等于pivot,且rightleft的时候,right左移注意:轴值用pivot保存第一轮分割序列
pivot=47和最后一个值互换
22=47,left向右移动
33=47,left向右移动
,不满足arr[left]=pivot把left的值赋给right
arr[right]=arr[left]
赋值过后,left不动,right向左移动
68=47,right向左移动
,不满足arr[right]=pivot把right的值赋给left
arr[left]=arr[right]
赋值过后,right不动,left向右移动
,left向右移动
3347,left向右移动
向右移动后,left==right,退出循环将pivot赋给arr[left]
至此,第一轮分割序列完成
第二轮分割序列---左子序列
经过第一轮分割,47左边的是左子序列,右边是右子序列
第二轮对左子序列分割,选择中间值作为pivot
12和33进行交换
,不满足arr[left]=pivot把arr[left]赋给arr[right]
arr[right]=arr[left]
赋值过后,left不动,right向左移动
29、33、33都比12大,所以right一直移动到下图位置
,right继续向左移动
此时right==left,终止循环把pivot赋给arr[left]
至此,左子序列1也分割完成了
小结
快排就是一个递归的过程,分割得到左子序列
再对左子序列进行快排分割,得到左子序列的左子序列....
处理完左边,再去处理右边的右子序列
第三轮分割序列---右子序列
右子序列只有47、68、49,选择48作为轴值pivot
pivot和最后一个值交换
47、49都比pivot=68小,left一直向右移动,直到left==right
分割之后,只剩下左子序列:47、49
47、49,选49作为轴值,得到左子序列47子序列只剩下一个元素47,就不必排序了,右边排序结束
结果:47、49、68
C++实现
选择中间的值作为轴值
总结