舍伍德线性时间选择
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
算法分析与设计实验报告
第 8次实验
通过这次实验,我回顾了舍伍德线性时间查找问题
附录:完整代码
#include
using namespace std;
//随机数类
const unsigned long maxshort=66536L;
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:n-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);
}
template
inline void Swap(Type &a,Type &b) {
Type temp = a;
a = b;
b = temp;
}
//计算a[l:r]中第k小元素
template
Type select(Type a[],int l,int r,int 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] 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-j+l-1;//右侧:k-(j-l+1)=k-j+l-1 l = j + 1; } else { r = j - 1; } } } //计算a[0:n-1]中第k小元素 //假设a[n]是一个键值无穷大的元素 template Type select(Type a[],int n,int k) { if(k<1 || k>n) { cout<<"请输入正确的k!"< return 0; } return select(a,0,n-1,k); } int main() { int a[100] ={0}; int m,k; cout<<"请输入数组元素个数; "; cin>>m; cout<<"请输入需要查找第几个元素: "; cin>>k; srand(time(0)); cout<<"\n原数组为:"< for(int i=0; i a[i]=rand()%100;