线性时间元素选择-舍伍德算法
代码如下
RandomNumber.h
#pragma once
#include<ctime>
#include<fstream>
using namespace std;
const unsigned long maxshort = 65536L;
const unsigned long multiplier = 1194211693L;
const unsigned long adder = 12345L;
class RandomNumber {
private:
unsigned long randSeed; //当前种子
public:
RandomNumber(unsigned long s = 0);//构造函数,默认值0表示由系统自动产生种子
unsigned short Random(unsigned long n);//产生0:0-1之间的随机整数
double fRandom(void);//产生(0,1)之间的随机实数
};
RandomNumber::RandomNumber(unsigned long s) {
if (s == 0) {
randSeed = time(0);
}
else {
randSeed = s;
}
}
unsigned short RandomNumber::Random(unsigned long n) {
randSeed = multiplier * randSeed + adder;
return (unsigned short)((randSeed >> 16) % n);
}
double RandomNumber::fRandom(void) {
return Random(maxshort) / double(maxshort);
}
int TossCoins(int numberCoins) {
static RandomNumber coinToss;
int i, tosses = 0;
for (i = 0; i < numberCoins; i++) {
tosses += coinToss.Random(2);
}
return tosses;
}
void CreateDataFun(int n) {
ofstream out;
out.open("4.txt");
RandomNumber r;
unsigned long s;
for (int i = 0; i < n; i++) {
s = r.Random(n);
out << s << ' ';
}
}
线性时间元素选择.cpp
#include<iostream>
//#include<fstream>
#include<cmath>
#include"RandomNumber.h"
#define maxvalue 32767
using namespace std;
template <class Type>
inline void Swap(Type& a, Type& b)
{
Type temp = a;
a = b;
b = temp;
}
template <class Type>
Type select(Type a[], int l, int r, int k) { //计算a[l:r]中第k小元素
static RandomNumber rnd;
while (true) {
if (l >= r)
{
return a[l];
}
int i = l,
j = l + rnd.Random(r - l + 1);//随机选择划分基准
Swap(a[i], a[j]);
j = r + 1;
Type pivot = a[l];
//以划分基准为轴做元素交换
while (true)
{
while (a[++i] < pivot);
while (a[--j] > pivot);
if (i >= j)
{
break;
}
Swap(a[i], a[j]);
}
if (j - l + 1 == k)//第k小
{
return pivot;
}
//a[j]必然小于pivot,做最后一次交换,满足左侧比pivot小,右侧比pivot大
a[l] = a[j];
a[j] = pivot;
//对子数组重复划分过程
if (j - l + 1 < k)
{
k = k - j + l - 1;//右侧:k-(j-l+1)=k-j+l-1
l = j + 1;
}
else
{
r = j - 1;
}
}
}
template <class Type>
Type Select(Type a[], int n,int k) {
if (k<1 || k>n) {
cout << "Error! OutOfBound!"<<endl;
return maxvalue;
}
return select(a, 0, n - 1, k);
}
int main() {
//CreateDataFun(10000);
//CreateDataFun(100);
#if 1
ofstream out;
out.open("output.txt");
ifstream in;
in.open("4.txt");
int n,k;
in >> n>>k;
int* a = new int[n];
for (int i = 0; i < n; i++) {
in >> a[i];
}
out << "所给数组第"<<k<<"小元素为:" << Select(a, n, k) << endl;
#endif
return 0;
}
参考资料:《计算机算法设计与分析》第五版