hnu 数据结构 实验八

实验8 查找算法实验比较

实验目的

基于教材内容,从顺序查找、二分查找、基于BST的查找和哈希中任选两种查找算法,实现并比较性能。

基本要求

(1)对实现的查找算法进行实验比较,在不同数据规模(N)下执行100次成功查找,以表格形式记录最小、最大和平均查找时间;在不同数据规模(N)下执行100次不成功查找,以表格形式记录最小、最大和平均查找时间。

(2)查找算法要基于教材,测试输入的整数数据文件(5个,文件中数据规模N分别是100,1K,10K,100K和1M),每次查找的比较次数和时间也要输出到文件中。

(3)提交最终实验作业。用附件的形式,提交两个文件:一个压缩包(包含源码和5个用于查找测试的数据文件);一个pdf文档(文档中包含实验日志和一个根据基本要求(1)记录实验结果的表格,然后进行适当的实验结果分析)。

实验八-查找算法实验比较-实验日志
【2020.12.26】
任务:复习教材关于二分查找、基于BST的查找和哈希查找的算法,理解算法思想,对算法的实现方式有一个总体的认识。

【2020.12.28】
任务:复习关于文件输入输出流的相关知识,复习关于rand函数的相关知识。构思关于随机数生成的格式。同时查资料了解关于计算查找时间代价的方法,得知了时钟频率LARGE_INTEGER frequency,可以用完成查找后的时钟频率减去之前的时钟频率,得出查找所用的时间。

【2020.12.29】
任务:完成随机生成数的main函数文件,分别生成大小为100,1K,10K,100K,1M大小的数据文件,再生成两个被查找数据的文件,分别包含了100个数据,一个是可以被查找到的100个数据,另一个是无法查找的100个数据,分别命名为“success.text”和“fail.txt”。

遇到问题1:打开文件后忘记关上文件了
出错原因:没有关上文件
修改方式:在一个文件输入结束后,加入close()函数,关闭文件
在这里插入图片描述

遇到问题2:
在这里插入图片描述
在这里插入图片描述

出错原因:上一个文件输入已将用过outfile这个输出了,在这里起了冲突。
修改方式:改成outfile1即可。同时其他文件的输出也要做相应改变。

遇到问题3:编译通过,但允许出错
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

出错原因:猜测是因为一维数组超空间了
改进方式:改用vector容器储存随机数
修改后运行成功。
在这里插入图片描述

五组随机数和两组测试数据生成工作完成。

【2021.1.1】
任务:完成顺序查找、哈希查找的实现,再根据时钟频率,完成每组数据成功和失败的各一百次查找,记录所用时间,制作相应表格。
顺序查找
在这里插入图片描述

哈希查找
在这里插入图片描述

结果分析:
顺序查找的时间复杂度为O(n),在规模增大时,可以明显看出其查找的平均时间增大.尤其是在查找失败的情况下,因为要将所有值遍历一次,从表格可以看出其平均时间和规模呈正比增长;
哈希查找的时间复杂度为O(1),在规模增大的情况下,可以看出平均时间消耗几乎一样。

可见,在进行查找时,不同的算法在数据量大规模增加时,所需要的时间代价差距十分悬殊,我们在平时的作业、练习中遇到的几乎都是规模很小的数据,这时候采取增长幅度大的算法可能感受不出来,一旦数据量几何式增长,代价大的算法很可能直接造成运行崩溃,所以我们应该对各种算法的时间、空间代价有一个基本的认识,尽量采用代价小的算法。

【2021.1.2】
任务:完善实验日志,上交实验代码和日志报告。

查找代码:

#include <iostream>
#include <time.h>
#include <algorithm>
#include <fstream>
#include <windows.h>
#include <vector>
#define random(a,b) (int)(((double)rand()/RAND_MAX)*pow(10,rand()%7))
using namespace std;
const int maxn=1048576;
int C[maxn+5];//散列函数,取余法
LARGE_INTEGER frequency;//时钟频率
//const int maxn=1e7;//10M
double begin_,_end,dft,dff,dfm;

int main()
{
    srand((int)time(NULL));//time seed
    QueryPerformanceFrequency(&frequency);//获得时钟频率
	dff=(double)frequency.QuadPart;//取得频率

	double mint=100000,maxt=0,average=0;
	int yes[100],no[100];
    ifstream input1("success.txt");
	for(int i = 0 ; i < 100; i++)
        input1 >> yes[i];
    input1.close();

    ifstream input2("fail.txt");
	for(int i = 0 ; i < 100; i++)
        input2 >> no[i];
    input2.close();

    int n = 1000*10;
    cout <<"----------进行顺序查找----------" << endl;
    vector<int> num_list;int key;

    ifstream input3("10K.txt");
	for(int i = 0 ; i < 100; i++)
    {
        input3 >> key;
        num_list.push_back(key);
    }
    input3.close();

    ofstream outfile1("10K_time.txt");
    for(int i=0;i<100;i++)
	{
	  int x=yes[i];
	  int count=0;//查找次数
	  QueryPerformanceCounter(&frequency);
      begin_=frequency.QuadPart;//获得初始值1
      for(int j=0;j<n;j++)
      {
      	count++;
      	if(num_list[j]==x) break;
	  }
	  QueryPerformanceCounter(&frequency);
      _end=frequency.QuadPart;//获得终止值
      dfm=(double)(_end-begin_);//差值
      dft=dfm/dff;//差值除以频率得到时间
      cout<<"顺序表查找成功,查找次数为"<<count<<endl;
	  outfile1<<"顺序表查找成功,查找次数为"<<count<<endl;
	  mint=min(mint,dft*1000000);//最小时间
	  maxt=max(maxt,dft*1000000);//最大时间
	  average+=dft*10000;
	}
	cout<<"顺序表查找成功最小时间为"<<mint<<"μs"<<endl;
	outfile1<<"顺序表查找成功最小时间为"<<mint<<"μs"<<endl;
	cout<<"顺序表查找成功最大时间为"<<maxt<<"μs"<<endl;
	outfile1<<"顺序表查找成功最大时间为"<<maxt<<"μs"<<endl;
	cout<<"顺序表查找成功平均时间为"<<average<<"μs"<<endl;
	outfile1<<"顺序表查找成功平均时间为"<<average<<"μs"<<endl;

	cout << endl;
	outfile1 << endl;
	outfile1<<"----------顺序表查找失败------------"<<endl;
	for(int i=0;i<100;i++)
	{
	  int x=no[i];
	  int count=0;//查找次数
	  QueryPerformanceCounter(&frequency);
	  bool flag=false;
      begin_=frequency.QuadPart;//获得初始值
      for(int j=0;j<n;j++)
      {
      	count++;
      	if(num_list[j]==x)
      	{
		  flag=true;
		  break;
		}
	  }
	 QueryPerformanceCounter(&frequency);
     _end=frequency.QuadPart;//获得终止值
     dfm=(double)(_end-begin_);//差值
     dft=dfm/dff;//差值除以频率得到时间
     if(!flag)
    {
	 cout<<"顺序表查找失败,查找次数为"<<count<<endl;
	 outfile1<<"顺序表查找失败,查找次数为"<<count<<endl;
	  }
	 mint=min(mint,dft*1000000);//最小时间
	 maxt=max(maxt,dft*1000000);//最大时间
	 average+=dft*10000;
	}
	cout<<"顺序表查找失败最小时间为"<<mint<<"μs"<<endl;
	outfile1<<"顺序表查找失败最小时间为"<<mint<<"μs"<<endl;
	cout<<"顺序表查找失败最大时间为"<<maxt<<"μs"<<endl;
	outfile1<<"顺序表查找失败最大时间为"<<maxt<<"μs"<<endl;
	cout<<"顺序表查找失败平均时间为"<<average<<"μs"<<endl;
	outfile1<<"顺序表查找失败平均时间为"<<average<<"μs"<<endl;

	cout<<"----------哈希查找----------"<<average<<"μs"<<endl;
	outfile1<<"----------哈希查找----------"<<average<<"μs"<<endl;
	mint=100000,maxt=0,average=0;
	for(int i=0;i<100;i++)
	{
	  bool flag=false;
	  int x=num_list[i];
	  int ke=x%maxn;
	  int y=C[ke];
	  QueryPerformanceCounter(&frequency);
      begin_=frequency.QuadPart;//获得初始值1
      if(y==x) flag=true;
	  QueryPerformanceCounter(&frequency);
      _end=frequency.QuadPart;//获得终止值
      dfm=(double)(_end-begin_);//差值
      dft=dfm/dff;//差值除以频率得到时间
      if(flag)
      {
	  cout<<"hash查找成功"<<endl;
	  outfile1<<"hash查找成功"<<endl;
	  }
  	  mint=min(mint,dft*1000000);//最小时间
	  maxt=max(maxt,dft*1000000);//最大时间
	 average+=dft*10000;
	}
	cout<<"hash查找成功最小时间为"<<mint<<"μs"<<endl;
	outfile1<<"hash查找成功最小时间为"<<mint<<"μs"<<endl;
	cout<<"hash查找成功最大时间为"<<maxt<<"μs"<<endl;
	outfile1<<"hash查找成功最大时间为"<<maxt<<"μs"<<endl;
	cout<<"hash查找成功平均时间为"<<average<<"μs"<<endl;
	outfile1<<"hash查找成功平均时间为"<<average<<"μs"<<endl;
	cout << endl;
	outfile1<<"----------hash查找失败------------"<<endl;
	mint=100000,maxt=0,average=0;
	for(int i=0;i<100;i++)
	{
	  bool flag=false;
	  int x=no[i];
	  int ke=x%maxn;
	  int y=C[ke];
	  QueryPerformanceCounter(&frequency);
      begin_=frequency.QuadPart;//获得初始值1
      if(y==x) flag=true;
	  QueryPerformanceCounter(&frequency);
      _end=frequency.QuadPart;//获得终止值
      dfm=(double)(_end-begin_);//差值
      dft=dfm/dff;//差值除以频率得到时间
      if(flag){
	  cout<<"hash查找成功"<<endl;
	  outfile1<<"hash查找成功"<<endl;
	  }
	  else{
	   cout<<"hash查找失败"<<endl;
	   outfile1<<"hash查找失败"<<endl;
	  }
  	  mint=min(mint,dft*1000000);//最小时间
	  maxt=max(maxt,dft*1000000);//最大时间
	 average+=dft*10000;
	}
	cout<<"hash查找失败最小时间为"<<mint<<"μs"<<endl;
	outfile1<<"hash查找失败最小时间为"<<mint<<"μs"<<endl;
	cout<<"hash查找失败最大时间为"<<maxt<<"μs"<<endl;
	outfile1<<"hash查找失败最大时间为"<<maxt<<"μs"<<endl;
	cout<<"hash查找失败平均时间为"<<average<<"μs"<<endl;
	outfile1<<"hash查找失败平均时间为"<<average<<"μs"<<endl;
	outfile1.close();


    return 0;
}

/*#include <iostream>
#include <time.h>
#include <algorithm>
#include <fstream>
#include <windows.h>

using namespace std;
LARGE_INTEGER frequency;
double dff,begin_,_end,dfm,dft;

int main()
{
    QueryPerformanceFrequency(&frequency);//获得时钟频率
	dff=(double)frequency.QuadPart;//取得频率
	int yes[100],no[100];

	ifstream input1("success.txt");
	for(int i = 0 ; i < 100; i++)
        input1 >> yes[i];
    input1.close();

    ifstream input2("fail.txt");
	for(int i = 0 ; i < 100; i++)
        input2 >> no[i];
    input2.close();

    return 0;
}
*/

随机数生成代码:

#include <iostream>
#include <time.h>
#include <algorithm>
#include <vector>
#include <fstream>

using namespace std;

const int max_size = 1024*1024;//10M大小

int main()
{
    srand((int)time(NULL));//重置时间种子
    //string files[7]={"100.txt","1K.txt","10K.txt","100K.txt","1M.txt","success.txt","fail.txt"};
    //int myarray[max_size];
    vector<int> num_list;
    vector<int> yes_list;
    ofstream outfile("1M.txt");
    for(int i = 0 ; i < max_size ; i++)
    {
        int k= rand()%max_size;

        num_list.push_back(k);
        outfile <<num_list[i] << " ";
        if((i+1) % 10 == 0)
            outfile << endl;
    }
    outfile.close();

    ofstream outfile5("success.txt");
    for(int i = 0 ; i < 100 ; i++)
    {
        int k = rand()%max_size;
        if (find(num_list.begin(), num_list.end(), k) != num_list.end())
        {
            outfile5 << k << " ";
            yes_list.push_back(k);
        }
        else
            i--;
        if((i+1) % 10 == 0)
            outfile5 << endl;
        /*vector<int>::iterator s=find(num_list.begin(),num_list.end(),k);
        if( s !=array.end()) //找到
        {
            outfile << k;
        }
        else
            i--;
        */
    }
    outfile5.close();

    ofstream outfile6("fail.txt");
    for(int i = 0 ; i < 100 ; i++)
    {
        int k = rand()%max_size+150;
        if (find(num_list.begin(), num_list.end(), k) == num_list.end())
        {
            outfile6 << k << " ";
        }
        else
            i--;
        if((i+1) % 10 == 0)
            outfile6 << endl;
        /*vector<int>::iterator s=find(num_list.begin(),num_list.end(),k);
        if( s ==array.end()) //找到
        {
            outfile << k;
        }
        else
            i--;
        */
    }
    outfile6.close();

    ofstream outfile1("100.txt");
    for(int i = 0 ; i < 100 ; i++)
    {
        //int k = rand()%100;
        outfile1 << yes_list[i] << " ";
        if((i+1) % 10 == 0)
            outfile1 << endl;
    }
    outfile1.close();

    ofstream outfile2("1K.txt");
    for(int i = 0 ; i < 1024 ; i++)
    {
        if(i < 100)
        {
            //int k = rand()%100;
            outfile2 << yes_list[i] << " ";
        }
        else
        {
            int k = rand()%max_size;
            outfile2 << num_list[k] << " ";
        }
        if((i+1) % 10 == 0)
            outfile2 << endl;
    }
    outfile2.close();

    ofstream outfile3("10K.txt");
    for(int i = 0 ; i < 1024*10 ; i++)
    {
        if(i < 100)
        {
            //int k = rand()%100;
            outfile3 << yes_list[i] << " ";
        }
        else
        {
            int k = rand()%max_size;
            outfile3 << num_list[k] << " ";
        }
        if((i+1) % 10 == 0)
            outfile3 << endl;
    }
    outfile3.close();

    ofstream outfile4("100K.txt");
    for(int i = 0 ; i < 1024*100 ; i++)
    {
        if(i < 100)
        {
            //int k = rand()%100;
            outfile4 << yes_list[i] << " ";
        }
        else
        {
            int k = rand()%max_size;
            outfile4 << num_list[k] << " ";
        }
        if((i+1) % 10 == 0)
            outfile4 << endl;
    }
    outfile4.close();



    cout << "随机数生成成功" << endl;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值