算法分析第六次作业
1. 问题
给你一个序列让你找出第k大
2. 解析
写出一个快排,选定key,当左区间比他小的数大于k则递归左区间,小于k,则当前k减去小于的值,递归右区间,等于k则这个数就是我们要找的数
3. 设计
int FindKthMax(int*list, int left, int right, int k) {
int key = list[left];
int low = left, high = right;
while (low < high) {
while (list[high]>=key&&high > low)
high--;
list[low] = list[high];
while (list[low]<=key&&high>low)
low++;
list[high] = list[low];
}
list[low] = key;
/*实现一次快速排序*/
int l = right - low + 1;
if (l == k) //若key处恰好为第k大数,直接返回
return key;
else if (l < k)
/*l<k说明第k大数在key左边序列中,此时为第k-l大的数*/
FindKthMax(list, left, low - 1, k - l);
else
/*l>k说明第k大的数在右边序列中,位置还是第k大的数*/
FindKthMax(list, low + 1, right, k);
}
4. 分析
最坏复杂度O(nlogn)
5. 源码
https://github.com/Tinkerllt/algorithm-work.git
#include<iostream>
using namespace std;
int FindKthMax(int*list, int left, int right, int k);
int main() {
int i,n,k;
while (cin >> n) {
int *a = new int[n];
for (i = 0; i < n; i++)
cin >> a[i];
cin >> k;
cout << FindKthMax(a, 0, n - 1, k) << endl;
}
return 0;
}
int FindKthMax(int*list, int left, int right, int k) {
int key = list[left];
int low = left, high = right;
while (low < high) {
while (list[high]>=key&&high > low)
high--;
list[low] = list[high];
while (list[low]<=key&&high>low)
low++;
list[high] = list[low];
}
list[low] = key;
/*实现一次快速排序*/
int l = right - low + 1;
if (l == k) //若key处恰好为第k大数,直接返回
return key;
else if (l < k)
/*l<k说明第k大数在key左边序列中,此时为第k-l大的数*/
FindKthMax(list, left, low - 1, k - l);
else
/*l>k说明第k大的数在右边序列中,位置还是第k大的数*/
FindKthMax(list, low + 1, right, k);
}

浙公网安备 33010602011771号