1、算法思想
线性时间选择算法的思想和快速排序的思想基本一致,都是将基于序列分割完成的。
算法步骤:
2、代码实现
#include <iostream>
using namespace std;
/***********************************************************************
Input: a[]:待排数组序列 l:待排区间左下标,r:待排区间右下标
Output:
Description: 将数组序列的第一个元素作为枢纽元素x,将数组化分成
a[... x ...]。x左边的元素都小于x,右边的元素都大于x。
Return: 排序后枢纽元素的下标
Others:
************************************************************************/
template <class Type>
int Partition(Type a[],int l,int r)
{
Type x = a[l]; //枢纽元素(分割元素)
int i = l; //枢纽元素的索引号
int j = r; //a[]序列右边界索引号
while(i < j)
{
//从序列最右边开始查找,找到一个小于a[l]的为止;
while (a[j] >= x && i < j) --j;
if(i < j)
{
a[i] = a[j];
i++;
}
//从a[l]后面元素开始查找,找到一个比a[l]大的为止;
while (a[i] < x && i < j) ++i;
if (i < j)
{
a[j] = a[i];
j--;
}
}
a[i] = x; //将a[i]的值写回
return i; //返回分割点的索引
}
/***********************************************************************
Input: a[]:源数组序列 l:待选区间左下标,r:待选区间右下标
k: 查找第k大的元素
Output: a[l...r]区间内第k大的元素值
Description: 查找a[l...r]区间内第k大的元素值,并返回该值
Others:
************************************************************************/
template<class T>
T RandomSelect(T a[], int l, int r, int k)
{
if(l == r)
return a[l];
int i = Partition(a, l, r);
int j = i - l + 1;
if(k <= j)
{
return RandomSelect(a, l, i, k);
}
else
{
return RandomSelect(a, i+1, r, k - j);
}
}
int src[7] = {7,6,5,4,3,2,1};
int main()
{
cout << RandomSelect<int>(src, 0, 6, 1) << endl;
return 0;
}