用分治法实现元素选择
【问题描述】
给定线形序列集中n个元素和一个整数k,1≤k≤n,输出这n个元素中第k小元素的值及其位置。
注:使用分治法编程。
【输入形式】
第一行输入n的值,第二行输入n个数,中间用空格隔开,第三行输入k的值。
【输出形式】
n个数中的第k小元素的值及其位置,中间用空格隔开。
【样例输入】
5
8 1 3 6 9
4
【样例输出】
8
【样例说明】
第4小元素的值为8,位置为1(输入数据时的位置)
c++代码
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int Partition(int *A, int p ,int r)
{
int x = A[r];
int i = p-1;
for(int j = p;j<=r-1;j++)
{
if(A[j] <= x)
{
i++;
swap(A[i],A[j]);
}
}
swap(A[i+1],A[r]);
return i+1;
}
int Select(int *A, int p, int r, int i)
{
if(p==r)
return A[p];
int q = Partition(A,p,r);
int k = q-p+1;
if(i==k)
return A[q];
else if(i<k)
return Select(A,p,q-1,i);
else
return Select(A,q+1,r,i-k);
}
int A[30000];
int A1[30000];
int main()
{
int n,ii;
int mark=-1;
cin>>n;
for(int i = 1;i<=n;i++){
cin>>A[i];
A1[i]=A[i];
}
cin>>ii;
int ans = Select(A,1,n,ii);
for(int i = 1;i<=n;i++){
if(A1[i]==ans) mark=i;
}
cout<<ans<<" "<<mark<<endl;
}