快速排序

不想你离开。 提交于 2019-12-02 12:20:50
                                    **快速排序**

快速排序的基本思想:
首先选第一个数作为分界数据,
将比它小的数据存储在它的左边,比它大的数据存储在它的右边,它存储在左、右两个子集之间。
这样左、右子集就是原问题分解后的独立子问题。
再用同样的方法,继续解决这些子问题,直到每个子集只有一个数据,就完成了全部数据的排序工作。

利用快速排序算法的思想,来解决选择问题。
记一趟快速排序后,分解出左子集中元素个数为 nleft,则选择问题可能是以下几种情况之一:
nleft =k﹣1,则分界数据就是选择问题的答案。
nleft >k﹣1,则选择问题的答案继续在左子集中找,问题规模变小了。
nleft <k﹣1,则选择问题的答案继续在右子集中找,问题变为选择第k-nleft-1 小的数,问题的规模变小了。

此算法在最坏情况时间复杂度为 O(n2) ,此时nleft总是为0,左子集为空,即第k小元素总是位于right子集中。
平均时间复杂度为 O(n )。

int select (int left, int right, int k){
	if(left>=right) return a[left];
	int i=left;	int j=right+1;
	int pivot=a[left];
	while(true){
		do{	i=i+1;}while(a[i]<pivot);
		do{	j=j-1;}while(a[j]>pivot);
		if(i>=j) break;
		swap(a[i],a[j]);
	}
	if(j-left+1==k) return pivot;
	a[left]=a[j];
	a[j]=pivot;
	if(j-left+1<k) //j-left+1 :左区元素的个数
		return select(j+1,right,k-j+left-1); //在右区中找
	else
		return select(left,j-1,k);
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!