快速排序
下面是之前实现过的快速排序的代码。
function quickSort(a,left,right){ if(left<right){ let mid=partition(a,left,right);//选出key下标 quickSort(a,left,mid-1);//对key的左半部分排序 quickSort(a,mid+1,right)//对key的右半部份排序 } } function partition(a,left,right){ let key=a[left];//一开始让key为第一个数 while(left<right){//扫描一遍 while(key<=a[right]&&left<right){//如果key小于a[right],则right递减,继续比较 right--; } [a[left],a[right]]=[a[right],a[left]];//交换 while(key>=a[left]&&left<right){//如果key大于a[left],则left递增,继续比较 left++; } [a[left],a[right]]=[a[right],a[left]];//交换 } return left;//把key现在所在的下标返回 }
明显我们可以看出快排的思想是每次找到一个基准数,将数组排列成基准数左边的每个数都比基准数大,右边的每个数都比基准数小的序列。 通过这个思想,我们可以稍微修改QuickSort函数,使它变成QuickSearch函数,使之拥有快速查找前k个最大的数。
基于快速排序思想查找第K大的数
function quickSearch(a,left,right,k){ if(k<1||k>right-left+1) return -1;//重点1,当k的值不符合要求时,返回-1 if(left==right) return a[left];//重点2,递归的结束条件 let key=-1,len=0; if(left<right){ key=partition(a,left,right); len=right-key+1; if(len==k){//重点3,递归的结束条件 return a[key]; } else if(len>k){ return quickSearch(a,key+1,right,k); } else{ return quickSearch(a,left,key-1,k-len); } } return key; } function partition(a,left,right){ let key=a[left];//一开始让key为第一个数 while(left<right){//扫描一遍 while(key<=a[right]&&left<right){//如果key小于a[right],则right递减,继续比较 right--; } [a[left],a[right]]=[a[right],a[left]];//交换 while(key>=a[left]&&left<right){//如果key大于a[left],则left递增,继续比较 left++; } [a[left],a[right]]=[a[right],a[left]];//交换 } return left;//把key现在所在的下标返回 } let arr=[5,4,3,2,1,6]; let kmax=quickSearch(arr,0,5,2); console.log(kmax);
重点是要注意判定边界条件,left,right,k三个都在变,因此需要检验
同理,还可以求第K小的数
运行结果: