**快速排序**
快速排序的基本思想:
首先选第一个数作为分界数据,
将比它小的数据存储在它的左边,比它大的数据存储在它的右边,它存储在左、右两个子集之间。
这样左、右子集就是原问题分解后的独立子问题。
再用同样的方法,继续解决这些子问题,直到每个子集只有一个数据,就完成了全部数据的排序工作。
利用快速排序算法的思想,来解决选择问题。
记一趟快速排序后,分解出左子集中元素个数为 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);
}
来源:https://blog.csdn.net/qq_45356160/article/details/102760081