-
利用快速排序的特点:第一遍排序会确定一个数的位置,这个数左边都比它大,右边都比他小(降序),当左边区间大于K时,说明我们求的第K大数在左边区间,这时我们可以舍弃右边区间,将范围缩小到左边区间从而重复上述过程,直到确定一个数的位置时,左边区间的小是K-1那么这个数字就是我们所求。右边同理。
能够使用这种方法的前提条件是:n个数不能重复。如果n个数中有重复,那么区间的大小不能保证就是第K大。可以用HASH判重来将重复的数据去掉。然后再使用上述方法。
- #include <iostream>
- using namespace std;
- template <class T>
- int quick2_sort(T a[],int low,int high)
- {
- T temp=a[low];
- int pos=low;
- int i=low,j=high;
- while(i<j)
- {
- while(i<j && a[j]>temp)
- j--;
- if(i<j)
- {
- a[pos]=a[j];
- pos=j;
- }
- while(i<j && a[i]<temp)
- i++;
- if(i<j)
- {
- a[pos]=a[i];
- pos=i;
- }
- }
- a[pos]=temp;
- return pos;
- }
- //递归实现
int findkth(int* arr, int begin, int end, int k){int pos = partition(arr, begin, end);//递归的结束条件为某一记录刚好划分到第k个位置//由于数组从0开始,所以需要加1了if (pos == k-1){return arr[pos];}else if (pos < k-1){findkth(arr, pos+1, end, k);}else{findkth(arr, begin, pos-1, k);}}
- //利用快速排序的思想查找第K大的数值
- //第一个参数代表要查找的数组
- //第二个参数代表数组的长度
- //第三个参数代表要查找第几大的元素
- //非递归
- template <class T>
- T findkth(T a[],int n,int k)
- {
- int low=0,high=n-1;
- while(1)
- {
- int pos=quick2_sort(a,low,high);
- if(pos==n-k)
- return a[pos];
- else if(pos<n-k)
- {
- low=pos+1;
- high=n-1;
- }
- else if(pos>n-k)
- {
- high=pos-1;
- low=0;
- }
- }
- }
- int main()
- {
- int a[11]={78934,234,65,32,543,354,567,3412,23,547,423};
- cout<<findkth(a,11,4)<<endl;
- return 0;
- }
最大的k个数即第k大数右边所有的数(包括自身)