本算法的参数中p为数组名,length为所处理的数组的长度。
//递归算法实现效率实在太低,因此选用含有递归思想的迭代法完成该选择问题
//将该函数定义为函数模板,使得算法能够更加通用
template<typename T>
unsigned MinK(int* p, const unsigned& k, const unsigned& length)//将类型定义为无符号整型方便编译器优化提速
{
//函数中均采用构造函数的方法初始化变量,效率优于使用赋值运算符初始化
T max(p[1]);
unsigned MaxPos(1);
//算法第一步:在数组的前K个数中找出最大值(这种情况相当于递归中的递归基),并将该集合作为初始集合
for (unsigned i(2); i <= k; ++i)
{
if (p[i] <= max)continue;//将出现几率较大的比较放在前面,有利于提高算法的效率
max = p[i];
MaxPos = i;
}
//算法第二步:每次从剩下的元素中加入一个元素进行判断,需要分为两大类情况
for (unsigned i(k + 1); i <= length; ++i)
{
if (p[i] >= max)//如果新加入集合的元素比之前集合中第K大的元素要大,则加入之后对集合的前K大元素仍然没有影响,直接忽略即可
continue;
else//如果新加入的元素比之前集合中第K大的元素小,则用其替换之前第K大的元素并重新求前K小的元素的最大值作为集合中第K大的元素
{
p[MaxPos] = p[i];
max = p[1];
MaxPos = 1;
for (unsigned j(2); j <= k; ++j)
{
if (p[j] <= max)continue;//将出现几率较大的比较放在前面,有利于提高算法的效率
max = p[j];
MaxPos = j;
}
}
}
return max;//经过多次迭代后返回第K小的元素
}