线性时间寻找一列无序数中第k大的数
分治思想
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#define N 100005
using namespace std;
int partition(int a[], int s, int e)
{
int m = (s + e) / 2;
int i = s, j = e;
int pivot = a[s];
while (i < j)
{
while (i < j && a[j] >= pivot)
j--;
swap(a[i], a[j]);
while (i < j &&a[i] <= pivot)
i++;
swap(a[i], a[j]);
}
return i;
}
int search(int a[], int s, int e, int k)
{
if (s == e) return a[s];
else
{
int pivot = partition(a, s, e);
int tmp = pivot - s + 1;//位于枢轴左边的元素个数(包括枢轴)
if (tmp == k)//枢轴正好位于第k大的数的位置
return a[s + k - 1];
if (tmp > k)//从左半边找第k大的数
return search(a, s, pivot - 1, k);
else//从右半面找第k-tmp大的数
return search(a, pivot + 1, e, k - tmp);
}
}
int main()
{
freopen("e:\\input.txt", "r", stdin);
int k,n;
int a[N];
scanf("%d",&n);
for (int i = 0; i < n; i++)//生成n个随机数,并存入数组
// scanf("%d", &a[i]);
{
a[i] = rand();
printf("%d ", a[i]);
}
printf("\n");
for (int i = 1; i <= n;i++)//输出第k小的数,k为1,2,3...n
{
int ans = 0;
ans = search(a, 0, n - 1, i);
printf("%d\n", ans);
}
return 0;
}