查找算法1

实验目的
基于教材内容,从顺序查找、二分查找、基于 BST 的查找和哈希中任选两种查找算法,实现并比较性能。
基本要求
(1)对实现的查找算法进行实验比较,在不同数据规模(N)下执行 100 次成功查找,以表格形式记录最小、最大
和平均查找时间;在不同数据规模(N)下执行 100 次不成功查找,以表格形式记录最小、最大和平均查找时间。
(2)查找算法要基于教材,测试输入的整数数据文件5 个,文件中数据规模 N 分别是 100,1K,10K,100K 和 1M),
每次查找的比较次数和时间也要输出到文件中。
(3)提交最终实验作业。用附件的形式,提交两个文件:一个压缩包(包含源码和 5 个用于查找测试的数据文件)
一个 pdf 文档(文档中包含实验日志和一个根据基本要求
(1)记录实验结果的表格,然后进行适当的实验结果分析)。
(4)记录实验结果的表格,然后进行适当的实验结果分析
1.首先生成测试数据用于测试,即编写 5 个不同大小的随机数生成函数
首先定义 7 个 TXT 文件,包括随机数文件 5 个和 SUCCESS 文件和 FAIL 文件,以确保随机数生成
正确性。
生成随机数 1M,记录在数组中,用另一个数组记录是否产生随机数。
装载 5 个 TXT 文件,打开文件,对文件中随机数进行输出,关闭文件。
对 SUCCESS 文件和 FAIL 文件执行同样的操作。
随机数生成文件完成,另,采用 HASH 查找和二分查找,在随机数生成文件中需要对此两个查找函
数进行重载。代码示例:
#include <iostream>
#include<cstdlib>
#include<cstring>
#include <time.h>
#include <fstream>
#include <math.h>
#define random(x) (int)(((double)rand()/RAND_MAX)*pow(10,rand()%x))
using namespace std;
const int maxn=1e7;//10M
bool hashtable[10*maxn+5]={0};//记录随机数是否发生
int array[maxn+5]={0};//存储产生的随机数
int su[105]={0},fa[105]={0};
double begin_,_end,dft,dff,dfm;
void Init(fstream &infile,int A[])//从文件输入,函数重载
{
int a,i=0;
while(!infile.eof()&&i<maxn)
{
infile>>a;
A[i]=a;
i++;
}
}
void print(fstream &outfile,int n,int A[])//输出
{
for(int i=0;i<n;i++)
{
outfile<<A[i]<<endl;
}
}
void Init(fstream &infile,int A[],bool Hash[])//从文件输入,函数重载
{int a,i=0,key;
fill(Hash,Hash+maxn,0);//初始化 hash 表
while((!infile.eof())&&i<maxn)
{
infile>>a;
A[i]=a;
key=a%maxn;
Hash[key]=1;//key(x)=x;hash 函数定义为线性 hash
i++;
}
}
int main()
{
//srand((int)time(NULL));//time seed
string files[7]={"100.txt","1k.txt","10k.txt","100k.txt","1M.txt","sucess.txt","fail.txt",};
fstream file;
for(int i=0;i<maxn/10;i++)
{//随机产生 1M 的数据
array[i]=random(7);
hashtable[array[i]]=1;
}
int k=100;
for(int i=0;i<5;i++)//装载 5 个 test 文件
{
file.open(files[i].c_str(),ios::out);//打开文件
print(file,k,array);
file.close();//关闭文件
k*=10;
}
file.open(files[5].c_str(),ios::out);
print(file,100,array);//成功查找数据文件
file.close();
file.open(files[6].c_str(),ios::out);
int num=0,number=0;
number=random(7);
while(number=random(7),hashtable[number]||num<100)
{
if(!hashtable[number])
{
file<<number<<endl;
num++;
}}
file.close();
cout<<"随机数产生成功!"<<endl;
return 0;
}
2. 接下来是对每一组测试数据分别进行 100 次成功和失败查找
采用的是 hash 查找和二分查找,分别测试查找性能。
.输出信息汇总在 TXT 文件里,另外整体数据的平均查找时间以及最大最小查找时间需要分别手动填
写在一个表格里(数据量很少)
二分查找函数
HASH 函数
void hashsearch(fstream &outfile,bool H[],int S[],int F[])//hash 散列查找
{
double mints=100,maxts=0,averages=0;
double mintf=100,maxtf=0,averagef=0;
bool flag;int Test;
int num=1;
for(int i=0;i<200;i++)//100 次成功查找
{
flag=0;
Test=(i<100)?S[i%100]:F[i%100];
QueryPerformanceCounter(&frequency);
begin_=frequency.QuadPart;//获得初始值
if(H[Test]) flag=1;//查找成功
QueryPerformanceCounter(&frequency);
_end=frequency.QuadPart;//获得终止值
dfm=(double)(_end-begin_);//差值
dft=dfm/dff;//差值除以频率得到时间
if(flag)
{
cout<<"hash 查找记录:"<<Test<<"->成功
"<<"查找次数:"<<num<<"
次";
outfile<<"hash 查找记录:"<<Test<<"->成功
"<<"查找次数:"<<num<<"
次";
mints=min(mints,dft*1000);//最小时间
maxts=max(maxts,dft*1000);//最大时间
averages+=dft*10;//平均时间
}
else
{
cout<<"hash 查找记录:"<<Test<<"->失败
"<<"查找次数:"<<num<<"
次";
outfile<<"hash 查找记录:"<<Test<<"->失败
"<<"查找次数:"<<num<<"
次";
mintf=min(mintf,dft*1000);//最小时间
maxtf=max(maxtf,dft*1000);//最大时间
averagef+=dft*10;//平均时间
}
cout<<"查找时间: "<<dft*1000<<"ms"<<endl;
outfile<<"查找时间: "<<dft*1000<<"ms"<<endl;
}
cout<<"hash 查找成功: 最小查找时间 mints="<<mints<<"ms
"<<"最大查找时间
maxts="<<maxts<<"ms
"<<"平均查找时间 averages="<<averages<<"ms\n 查找结束\n";
outfile<<"hash 查找成功:最小查找时间 mints="<<mints<<"ms
"<<"最大查找时间
maxts="<<maxts<<"ms
"<<"平均查找时间 averages="<<averages<<"ms\n 查找结束\n";
cout<<"hash 查找失败:最小查找时间 mintf="<<mintf<<"ms
"<<"最大查找时间maxtf="<<maxtf<<"ms
"<<"平均查找时间 averagef="<<averagef<<"ms\n 查找结束\n";
outfile<<"hash 查找失败:最小查找时间 mintf="<<mintf<<"ms
"<<"最大查找时间
maxtf="<<maxtf<<"ms
"<<"平均查找时间 averagef="<<averagef<<"ms\n 查找结束\n";
}
代码示例:
#include <iostream>
#include <cmath>
#include <time.h>
#include <algorithm>
#include <fstream>
#include <windows.h>
#define random(a,b) (int)(((double)rand()/RAND_MAX)*pow(10,rand()%7))
using namespace std;
LARGE_INTEGER frequency;//时钟频率
const int maxn=1e7;//10M
bool hashtable[10*maxn+5]={0};//记录随机数是否发生
int array[maxn+5]={0};//存储产生的随机数
int su[105]={0},fa[105]={0};
double begin_,_end,dft,dff,dfm;
void Init(fstream &infile,int A[])//从文件输入,函数重载
{
int a,i=0;
while(!infile.eof()&&i<maxn)
{
infile>>a;
A[i]=a;
i++;
}
}
void print(fstream &outfile,int n,int A[])//输出
{
for(int i=0;i<n;i++)
{
outfile<<A[i]<<' ';
}
}
void Init(fstream &infile,int A[],bool Hash[])//从文件输入,函数重载
{
int a,i=0,key;
fill(Hash,Hash+maxn,0);//初始化 hash 表
while((!infile.eof())&&i<maxn)
{
infile>>a;
A[i]=a;key=a%maxn;
Hash[key]=1;//key(x)=x;hash 函数定义为线性 hash
i++;
}
}
void binarysearch(fstream& outfile,int A[],int n,int S[],int F[])//二分查找
{
sort(A,A+n);//升序排列
int mid,num=0,x,left,right;//中间值和比较次数
double mints=100,maxts=0,averages=0;
double mintf=100,maxtf=0,averagef=0;
bool flag;
for(int i=0;i<200;i++)//100 次成功查找
{
x=(i<100)?S[i%100]:F[i%100];//确定待查找的数 x
num=0;//初始化查找次数为 0
left=0,right=n-1;
flag=0;
QueryPerformanceCounter(&frequency);
begin_=frequency.QuadPart;//获得初始值
while(left<=right)//二分查找
{
num++;//比较次数加一
mid=(left+right)/2;//优化 mid=left+(right-left)/2;防止溢出
if(A[mid]==x)
{
flag=1;//查找成功
break;
}
else if(A[mid]>x) right=mid-1;//避免相邻区间整形/2,查找不到的情况
else left=mid+1;
}
QueryPerformanceCounter(&frequency);
_end=frequency.QuadPart;//获得终止值
dfm=(double)(_end-begin_);//差值
dft=dfm/dff;//差值除以频率得到时间
if(flag)//查找成功
{
cout<<"二分查找记录->"<<x<<"->成功
"<<"查找次数: "<<num<<"次";
outfile<<"二分查找记录:"<<x<<"->成功
"<<"查找次数: "<<num<<"次
";
mints=min(mints,dft*1000);//最小时间maxts=max(maxts,dft*1000);//最大时间
averages+=dft*10;//平均时间
}
else
{
cout<<"二分查找记录->"<<x<<"->失败
"<<"查找次数: "<<num<<"次";
outfile<<"二分查找记录:"<<x<<"->失败
"<<"查找次数: "<<num<<"次
";
mintf=min(mintf,dft*1000);//最小时间
maxtf=max(maxtf,dft*1000);//最大时间
averagef+=dft*10;//平均时间
}
cout<<"查找时间: "<<dft*1000<<"ms"<<endl;
outfile<<"查找时间: "<<dft*1000<<"ms"<<endl;
}
cout<<"二分查找成功:最小查找时间 mints="<<mints<<"ms
"<<"最大查找时间
maxts="<<maxts<<"ms
"<<"平均查找时间 averages="<<averages<<"ms\n 查找结束\n";
outfile<<"二分查找成功:最小查找时间 mints="<<mints<<"ms
"<<"最大查找时间
maxts="<<maxts<<"ms
"<<"平均查找时间 averages="<<averages<<"ms\n 查找结束\n";
cout<<"二分查找失败:最小查找时间 mintf="<<mintf<<"ms
"<<"最大查找时间
maxtf="<<maxtf<<"ms
"<<"平均查找时间 averagef="<<averagef<<"ms\n 查找结束\n";
outfile<<"二分查找失败:最小查找时间 mints="<<mintf<<"ms
"<<"最大查找时间
maxtf="<<maxtf<<"ms
"<<"平均查找时间 averagef="<<averagef<<"ms\n 查找结束\n";
}
void hashsearch(fstream &outfile,bool H[],int S[],int F[])//hash 散列查找
{
double mints=100,maxts=0,averages=0;
double mintf=100,maxtf=0,averagef=0;
bool flag;
int Test;
int num=1;
for(int i=0;i<200;i++)//100 次成功查找
{
flag=0;
Test=(i<100)?S[i%100]:F[i%100];
QueryPerformanceCounter(&frequency);
begin_=frequency.QuadPart;//获得初始值
if(H[Test]) flag=1;//查找成功
QueryPerformanceCounter(&frequency);
_end=frequency.QuadPart;//获得终止值
dfm=(double)(_end-begin_);//差值dft=dfm/dff;//差值除以频率得到时间
if(flag)
{
cout<<"hash 查找记录:"<<Test<<"->成功
"<<"查找次数:"<<num<<"
次";
outfile<<"hash 查找记录:"<<Test<<"->成功
"<<"查找次数:"<<num<<"
次";
mints=min(mints,dft*1000);//最小时间
maxts=max(maxts,dft*1000);//最大时间
averages+=dft*10;//平均时间
}
else
{
cout<<"hash 查找记录:"<<Test<<"->失败
"<<"查找次数:"<<num<<"
次";
outfile<<"hash 查找记录:"<<Test<<"->失败
"<<"查找次数:"<<num<<"
次";
mintf=min(mintf,dft*1000);//最小时间
maxtf=max(maxtf,dft*1000);//最大时间
averagef+=dft*10;//平均时间
}
cout<<"查找时间: "<<dft*1000<<"ms"<<endl;
outfile<<"查找时间: "<<dft*1000<<"ms"<<endl;
}
cout<<"hash 查找成功: 最小查找时间 mints="<<mints<<"ms
"<<"最大查找时间
maxts="<<maxts<<"ms
"<<"平均查找时间 averages="<<averages<<"ms\n 查找结束\n";
outfile<<"hash 查找成功:最小查找时间 mints="<<mints<<"ms
"<<"最大查找时间
maxts="<<maxts<<"ms
"<<"平均查找时间 averages="<<averages<<"ms\n 查找结束\n";
cout<<"hash 查找失败:最小查找时间 mintf="<<mintf<<"ms
"<<"最大查找时间
maxtf="<<maxtf<<"ms
"<<"平均查找时间 averagef="<<averagef<<"ms\n 查找结束\n";
outfile<<"hash 查找失败:最小查找时间 mintf="<<mintf<<"ms
"<<"最大查找时间
maxtf="<<maxtf<<"ms
"<<"平均查找时间 averagef="<<averagef<<"ms\n 查找结束\n";
}
int main()
{
srand((int)time(NULL));//time seed
string files[12]={"100.txt","1k.txt","10k.txt","100k.txt","1M.txt","sucess.txt","fail.txt",
"out_100.txt","out_1k.txt","out_10k.txt","out_100k.txt","out_1M.txt"};
fstream file;
//产生测试文件结束,开始查找
QueryPerformanceFrequency(&frequency);//获得时钟频率
dff=(double)frequency.QuadPart;//取得频率file.open(files[5].c_str(),ios::in);
Init(file,su);//输入成功查找数据
file.close();
file.open(files[6].c_str(),ios::in);
Init(file,fa);
file.close();//输入失败查找数据
for(int i=0;i<100;i++)
{
cout<<fa[i]<<endl;
}
for(int i=0;i<5;i++)//对 5 个测试文件进行二分查找和 hash 查找
{
file.open(files[i].c_str(),ios::in);//打开测试文件
Init(file,array,hashtable);//初始化文件将数据填入序列 arr 中并且标记 hash 表
file.close();
file.open(files[i+7].c_str(),ios::out);//打开测试文件
cout<<"数据规模为"<<100*pow(10,i)<<"的数据进行 hash 查找,结果如下"<<endl;
file<<"数据规模为"<<100*pow(10,i)<<"的数据进行 hash 查找,结果如下"<<endl;
hashsearch(file,hashtable,su,fa);
cout<<"---------------------------------------------------------"<<endl;
cout<<"数据规模为"<<100*pow(10,i)<<"的数据进行 binary 查找,结果如下"<<endl;
file<<"数据规模为"<<100*pow(10,i)<<"的数据进行 binary 查找,结果如下"<<endl;
binarysearch(file,array,100*pow(10,i),su,fa);
file.close();//关闭文件
}
return 0;
}
测试结果汇总

 

 

posted @ 2023-01-04 17:42  陌初  阅读(28)  评论(0)    收藏  举报