舍伍德算法 线性时间选择

xiaoxiao2021-02-28  101

 记录一下      算法分析实验七   

利用Sherwood型随机化思路求解线性时间选择算法,并计算出程序运行所需要的时间。

① 参考课件、教材、其它资料,将伪代码改成正式程序代码。

② 用一组小数据,手工验证程序正确性,发现可能的错误并修复。

③ 自己设计代码,生成小、中、大规模数据,分别存到三个.txt文件。

④ 对三种规模的数据,检测程序运行时间,观察并记录结果和发现。

 

先贴一下用来生成随机数文本的代码:

/* #include <iostream> #include <fstream> #include <stdlib.h> using namespace std; int main() { fstream fso("50000.txt", ios::out); int i; for(i = 0; i < 50000; ++i) fso << rand() << ' '; fso.close(); fstream fsi("50000.txt", ios::in); int x[50000]; for(i = 0; i < 50000; ++i) fsi >> x[i]; for(i = 0; i < 50000; ++i) cout << x[i] << '\t'; return 0; } */ //万级以下用这个缩小范围(四舍五入生成整数) #include<iostream> #include<stdlib.h> #include <fstream> #include<time.h> #include<iomanip> #include<stdio.h> #include<math.h> using namespace std; double round(double r) { return (r > 0.0) ? floor(r + 0.5) : ceil(r - 0.5); } double randomRange(double a, double b) { double x = (double)rand() / RAND_MAX; double result = x*(b - a) + a; return round(result); } int main() { srand((int)time(0)); fstream fso("10.txt", ios::out); int i; for(i = 0; i <10; ++i) fso <<randomRange(0, 100)<< ' '; // fso.close(); fstream fsi("10.txt", ios::in); int x[10]; for(i = 0; i <10; i++) fsi >> x[i]; for ( i = 0; i <10; i++) { cout << randomRange(0, 100) << " "; } cout << endl; system("pause"); }

主体代码:

#include<time.h> #include<stdio.h> #include<math.h> #include <iomanip> #include <iostream> #include <fstream> #include <stdlib.h> using namespace std; template<class Type> Type select(Type a[],int l,int r,int k); template<class Type> //是否越界 Type select(Type a[],int n,int k); template<class Type> void Shuffle(Type a[],int n); template <class Type> inline void Swap(Type &a,Type &b); int main() { int n,k,i; cout<<"输入三种数据选择元素规模:1.10;2.500;3.50000"<<endl; cin>>n; int *a=new int[n+1]; cout<<"求第k小个元素,请输入k:"<<endl; cin>>k; if(n==10) { fstream fsi("10.txt", ios::in); for(i = 0; i < 10; ++i) fsi >> a[i]; for(i = 0; i <10; ++i) cout << a[i] << '\t'; } else if(n==500) { fstream fsi("500.txt", ios::in); for(i = 0; i < 500; ++i) fsi >> a[i]; for(i = 0; i <500; ++i) cout << a[i] << '\t'; } else if(n==50000) { fstream fsi("50000.txt", ios::in); for(i = 0; i < 50000; ++i) fsi >> a[i]; for(i = 0; i <50000; ++i) cout << a[i] << '\t'; } cout<<endl; Shuffle(a,n); cout<<"数组洗牌后:"<<endl; for(i=0;i<n;i++) cout<<a[i]<< '\t'; cout<<endl; clock_t start,end,over; start=clock(); end=clock(); over=end-start; start=clock(); cout<<"数组第k小元素为:"<<select(a,n,k)<<endl; end=clock(); printf("The time is %6.3f",(double)(end-start-over)/CLK_TCK); cout<<endl; system("pause"); return 0; } //计算a[0:n-1]中第k小元素 //假设a[n]是一个键值无穷大的元素 template<class Type> Type select(Type a[],int n,int k) { if(k<1 || k>n) { cout<<"请输入正确的k!"<<endl; return 0; } return select(a,0,n-1,k); //合法 } //计算a[l:r]中第k小元素 template<class Type> Type select(Type a[],int l,int r,int k) { while(true) { if(l>=r) //数组仅1元素 { return a[l]; } int i = l; int 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; } //如果没找到(轴值不是第k小) //a[j]必然小于pivot,做最后一次交换,满足左侧比pivot小,右侧比pivot大 a[l] = a[j]; a[j] = pivot; //对子数组重复划分过程 if(j-l+1<k) //第k小在轴值右边 { k = k-j+l-1;//右侧:k-(j-l+1)=k-j+l-1 l = j + 1; } else //第k小在轴值左边 { r = j - 1; } } } template <class Type> inline void Swap(Type &a,Type &b) { Type temp = a; a = b; b = temp; } /* //随机洗牌算法 template<class Type> void Shuffle(Type a[],int n) { static Randomnumber rnd; //随机数类 for(int i=0; i<n; i++) { int j = rnd.Random(n-i)+i; //随机生成i~n之间的整数 Swap(a[i],a[j]); //随机选取的数作为基准值 } } */ //随机洗牌算法 template<class Type> void Shuffle(Type a[],int n) { srand((int)time(0)); double x,r; for(int i=0; i<n; i++) { x = (double)rand() / RAND_MAX; r = x*(n - i) + i; (r > 0.0) ? floor(r + 0.5) : ceil(r - 0.5); int j = (int)r; //随机生成i~n之间的整数 Swap(a[i],a[j]); //随机选取的数作为基准值 } } 不想用随机数类所以直接生成i~n随机数,运行起来似乎没有问题的样子。
转载请注明原文地址: https://www.6miu.com/read-2632360.html

最新回复(0)