先找一个中心
再找其他元素,小的放在中心元素之前,大的放在之后;
再对左右两个子表划分继续排序,用同样的方法,直到每个子表的元素只剩一个
子表是比原来的表更小的,用递归的思想
例子:
现在选21作为中心点,分成两个子表
左边的选8作为中心点,比他大的没有,后面只有一个元素
同理,右边的子表选第一个元素作为中心元素,比他小的调到前面,比他大的调到后头
前面的左子表只剩一个元素了,可以结束了,右边的继续.....
这就是快速排序的方法
基本思想:
具体实现:
称呼很多,随机取,选第一个元素49做中心点,这里再准备一个可以存放n个元素的空间,从第2个38开始看,小的从左往右放,大的从右往左放,相等的也放右边
其他元素就位了,然后中心点就可以放在这个位置了
缺点:还需要额外的空间,这次划分好后还得继续划分,当元素个数比较多时,这种方法太浪费空间了,不可取
这里在介绍另一种:只需要一个额外的位置就行了,
把中心点搬到零号位置,然后他的位置就可以使用了
再从后面搬一个比他小的值,是就搬到前面,不是就不搬,我们用low指向一号位置,high指向最后一个位置,我们从high开始--因为我们把第一个元素搬走了,前面空了,所有我从后面开始、
比我们中心点小就往前搬,不小就high--
这里27搬走了,他的位置就可以用了,这时我们从前面搬一个到后面去,这里27是刚搬过来的,所以我们看low的下一个38,他比中心点49小,不搬他,再继续low++,看下一个,65大,往后搬到high位置,
前面有空了,我们又可以从后往前搬了,看13是不是比49小,是就搬过去
再从前面搬一个大的
再搬一个小的,
这时不用搬了,没有了,low=high,区间内没有数据元素,然后将0号位置的中心点放在这里
两个子表:
再用同样的方法继续划分:
左边low是27,high是13,我们把low位置的元素27搬到0号位置,然后前面27这里原来的位置就空了,我们从后面找一个比他小的搬过来13,然后13原来这里就空了,
然后把38搬过去
然后这里low=high了,我们把27搬过来,通过中心点位置再划分两个子表,每个子表只有一个元素了,就结束了,这是左半部分
右半部分:
low是76,high是49
我们把low搬到0号位置,然后从后面找一个比76小的搬到前面,49搬过来
然后从前面搬一个大的过去,再从后面搬一个小的过来,然后重合。。。
特点:
1.交替式
2.递归算法
算法:
首先看主函数
对顺序表L排序,排序的范围是整个表,从1到L.length成员(第n个元素的位置)
知道low=1和high=n
依次划分:找到中心点元素的位置:Partition()
一个从low到中心点位置-1
一个从high到中心点位置+1
关键是找中心点:
low位置的元素放到0号位置:L.r[0]=L.r[low],
利用这个循环从后面找一个大的:如果high位置的值L.r[high].key比中心点的值pivotkey大,就本来在后头,我们再往前找--high
只有小于他,这个循环才不做了,否则反复循环,循环体是high--
结束循环:把high位置的元素搬到前面low指向的位置:L.r[low[=L.r[high]
再从前面找一个大的,若发现当前low位置的值小于中心点,就继续看下一个,++low
直到low的值比中心点的值大,循环才不做
把low位置的比较大的值搬到后面:L.r[high[=L.r[row]
继续,如果low<high,中间还有元素再来;
这里三个while都是ow<high,如果发现low和high重合了,就不做循环了
然后把第一个元素0号位置放到中心点,再返回low--即中心点元素的下标
做完操作后就知道中心点在哪了,他的返回值就是中心点的下标,
然后再分别用快速排序对两个子表进行同样的操作
这就是快速排序方法