算法分析第六次作业

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);
}

 

posted @ 2020-04-21 15:09  Tinker1998  阅读(105)  评论(0编辑  收藏  举报