Problem Description
输入一段序列,找出序列中第i小的数。
Input Description
第一行输入一个整数n(0<n<10000000)和一个整数i(1<=i<=n)。
第二行输入n个整数。
Output Description
输出第i小的整数。
Sample Input
10 5 1 2 3 4 5 6 7 8 9 10
Sample Output
5
找出第i小的整数
//找出第i小的元素
#include<stdio.h>
#include<stdlib.h>
int partition(int a[], int left, int right)
{
int i = left;
int j = right;
int t = rand() % (right - left + 1);
t = t + left;
int tmp = a[t];
a[t] = a[i];
a[i] = tmp;
while(i < j)
{
while(a[j] >= tmp && i < j)
{
j--;
}
a[i] = a[j];
while(a[i] <= tmp && i < j)
{
i++;
}
a[j] = a[i];
}
a[i] = tmp;
return i;
}
int select(int a[], int left, int right, int k)
{
if(left == right)
{
return a[left];
}
int i = partition(a, left, right);
int j = i- left + 1;
if(k <= j)
{
select(a, left, i,k);
}
else
{
select(a, i + 1, right, k - j);
}
}
int main()
{
int m, n;
scanf("%d %d", &n, &m);
int a[n];
for(int i = 0; i < n; i++)
{
scanf("%d", &a[i]);
}
int ans = select(a, 0, n -1, m);
printf("%d\n", ans);
return 0;
}
找出第i大的元素
//找出第i大的元素
#include<stdio.h>
#include<stdlib.h>
int partition(int a[], int left, int right)
{
int i = left;
int j = right;
int t = rand() % (right - left + 1);
t = t + left;
int tmp = a[t];
a[t] = a[i];
a[i] = tmp;
while(i < j)
{
while(a[j] >= tmp && i < j)
{
j--;
}
a[i] = a[j];
while(a[i] <= tmp && i < j)
{
i++;
}
a[j] = a[i];
}
a[i] = tmp;
return i;
}
int select(int a[], int left, int right, int k)
{
if(left == right)
{
return a[left];
}
int i = partition(a, left, right);
int j = right - i + 1;
if(k <= j)
{
select(a, i, right,k);
}
else
{
select(a, left, i - 1, k - j);
}
}
int main()
{
int m, n;
scanf("%d %d", &n, &m);
int a[n];
for(int i = 0; i < n; i++)
{
scanf("%d", &a[i]);
}
int ans = select(a, 0, n -1, m);
printf("%d\n", ans);
return 0;
}