哈希表的设计与实现 课程设计报告
哈希表课程设计报告
哈希表设计1 需求分析1.1 针对某个集体中的人名设计一个哈希表,使得平均查找长度不超过R,完成相应的建立和查表程序.1.2 人名为汉语拼音形式,最长不超过18个字符(如:庄双双 zhuangshuangshuang).1.3 假设待填入哈希表的人名有30个,平均查找长度为2。
哈希表用除留余数法构造,用伪随机探测在散列法处理冲突。
1.4 在输入人名过程中能自动识别非法输入,并给与非法输入的反馈信息要求重新输入。
1.5 测试数据:1)输入数据:zhangyun,mochengcheng,geyuwei,zhouruifeng,yuanyan,mengxiangyin, wuxudong,chenghusheng,wangqi,zhangxiuhua,xiongliying,leiyang,hanbingfeng, zhangchao,yaoboyu,liyingtao,liutong,wangyingli,lixiang,lvxiaohu,huanglei, zhouxiong,zhangxinxin,hexuyang,linyoulu,zhangxiao,chenzhi,dongchaoxun, wangxinyu,yuman,zhangyao.(在输入是可以输入非法数据来检验如:12345,zhuang shuangshuang,$%&^&*等等)2)查找输入:zhuangyuan 输出:查找成功输入:zhuangshuangshuang 输出:查找失败输入:mochengcheng 输出:查找成功输入:zhanglei 输出:查找失败(在输入时也输入非法数据来检验)2 概要设计2.1 哈希表的定义如下:class HashList_T{数据对象:D={A(i,j)={不多于18个字符的字符串}0=<i<18,0=<j<2};基本操作:void createHashList(void);操作结果:创建一个哈希表bool isLegal(string&s);前置条件:s是非空字符串后置条件:s合法字符串返回true,否则返回falsevoid show(bool lhs)const;前置条件:lhs被初始化后置条件:lhs为真打印查找成功,否则打印查找失败void findName(string&s);前置条件:哈希表已经建立,s非空后置条件:查找所输入的人名在不在哈希表中int getNumber(string&s)前置条件:s被初始化后置条件:返回s索引的值bool isFull(int i)const前置条件:变量i被初始化并且i不超过哈希表的长度后置条件:第i行的链表满了返回true,否则返回falsebool isExistence(int i,string&s)前置条件:参数被初始化后置条件:s存在返回true,否则返回false};2.2 主程序void main(){初始化;do{接受命令;处理命令;}while("命令"!="退出");}2.3本程序的模块只有两个模块:主程序模块和哈希表模块,调用关系为:主程序模块调用哈希表模块.3 详细设计3.1哈希表的私有成员为vector<string>的向量组,每一组的数据个数不超过2个3.2哈希表的基本操作设置:HashList_T(int numbers=1);HashList_T(const HashList_T&rhs);//初始化哈希表~HashList_T(void);//释放资源HashList_T& operator=(const HashList_T&rhs);//赋值函数void createHashList(void);//创建哈希表bool isLegal(string&s);//判断人名是否合法void show(bool lhs)const;//显示查找结果void findName(void);void findName(string&s);//查找特定姓名int getNumber(string&s);//得到索引号bool isExistence(int i,string&s);//第i行是否存在字符串sbool isFull(int i)const;//第i行向量是否满了其中部分操作的算法:HashList_T::HashList_T(int numbers){m_numbers=numbers;m_name_ptr=new vector<string>[m_numbers]; }HashList_T::~HashList_T(void){delete []m_name_ptr;}int HashList_T::getNumber(string&s){int i=s.size()%m_numbers;bool result=isFull(i);if(!result)return i;else{int j;if(m_numbers%2==0)j=m_numbers-1;elsej=m_numbers-2;i=(i+j)%m_numbers;result=isFull(i);while(result){i=(i+j)%m_numbers;result=isFull(i);}return i;}}void HashList_T::createHashList(void) {int i=0,numbers;string name;cout<<"输入要输入的人名总数:"<<endl;cin>>numbers;while(i<numbers+1){if(1){string s;cout<<"输入人名:"<<endl;cin>>s;name=s;}bool result=isLegal(name);while(!result){if(1){string s;cout<<"输入非法,输入人名:"<<endl;cin>>s;name=s;}result=isLegal(name);}int j=getNumber(name);m_name_ptr[j].push_back(name);i++;}}void HashList_T::findName(void){string name;int i=1;while(i>0){cout<<"输入查找人名"<<endl;cin>>name;bool result=isLegal(name);while(!result){cout<<"输入非法,再次输入人名"<<endl;cin>>name;}findName(name);cout<<"继续?yes--1.no--0"<<endl;cin>>i;}}bool HashList_T::isExistence(int i,string&s) {if(m_name_ptr[i].empty())return false;vector<string>::iterator p;int j;if(m_numbers%2==0)j=m_numbers-1;elsej=m_numbers-2;while(!m_name_ptr[i].empty()){p=m_name_ptr[i].begin();while(p!=m_name_ptr[i].end()){if(*p==s)return true;p++;}i=(i+j)%m_numbers;}return false;}3.3主程序算法:void main(){HashList_T hash(18);hash.createHashList();hash.findName();}4 程序调试4.1本次作业比较简单,只有一个核心算法就是构造散列函数的算法,在调试的时候发现string的问题(系统自带的),输入的人名不应该含有空格字符,否则回出现逻辑错误,这是程序的一个问题,如果要修改成char[]型处理方法类似就没改.在调试其他代码时候没有出现问题,比较顺利的调试成功.4.2有些函数不写系统会自己生成,为了避免出错自己写了上去只是声名并没有定义,如果用了编译器会报错.4.3算法改进:伪随机探查法能够消除基本聚集,但是如果两个关键子有相同的基位置, 那么他们就有同样的探查序列.采用双散列法能够避免这样,双散列函数使用两个和散列函数,第一个探查序列的起始值,第二个计算下一个位置的探查步长.4.4经验体会:借助DEBUG调试器和数据观察窗口,可以加快找到程序中的错误,采用软件工程的方法将程序划分层次结构使得代码设计时思路清晰,实现时调试顺利,得到了一次良好的程序设计训练.测试结果:输入要输入的人名总数:30输入人名: 输入人名:ASDGH mochengcheng输入非法,输入人名: 输入人名:#$%^&qwrd geyuwei输入非法,输入人名: 输入人名:zhuangshuangshuangshuang zhouruifeng输入非法,输入人名: 输入人名:Zhuangyun wangqi输入非法,输入人名: 输入人名:zhangyun zhangxiuhua输入人名: 输入人名:yuanyan xiongliying输入人名: 输入人名:mengxiangyin leiyang输入人名: 输入人名:wuxudong hanbingfeng 输入人名: 输入人名:chenghusheng yaoboyu输入人名: 输入人名:liyingtao lvxiaohu输入人名: 输入人名:liutong huanglei输入人名: 输入人名:wangyingli zhouxiong输入人名: 输入人名:lixiang zhangxinxin输入人名: 输入人名:hexuyang yuman输入人名: 输入人名:linyoulu zhangyao输入人名: 输入人名:zhangxiao zhangchao输入人名: 输入人名:chenzhi wangxinyu输入人名:dongchaoxun输入查找人名:zhuangzhuangzhuangfsff输入非法,再次输入人名qwer45465输入非法,再次输入人名$Zhff输入非法,再次输入人名mochengcheng查找成功继续?yes--1.no--01输入查找人名:zhangyun查找成功继续?yes--1.no--01输入查找人名:zhanglei查找失败继续?yes--1.no--01输入查找人名:leiyang查找成功继续?yes--1.no--0附录hashList.h 哈希表的声名hashList.cpp 哈希表的定义test.cpp 主程序hashList.h文件/*************************************************针对某个集体中的人名设计一个哈希表,使得平均查找长度不超过R 假设待填入哈希表的人名有30个,平均查找长度为2。
课程设计报告-哈希表
(此文档为word格式,下载后您可任意编辑修改!) 数据结构课程设计(哈希表的设计)院系专业班级学生姓名学号课程设计日期:2011年6月26日至2011年7 月7 日目录一、问题描述 (3)二、需求分析1、基本要求 (3)2、测试数据 (3)三、概要设计 (3)四、详细设计 (4)五、测试分析 (11)六、课程设计总结 (13)七、附录(源代码) (14)一、问题描述针对自己班级体中的“人名”设计一个哈希表,使得平均查找长度不超过R,完成相应的建表和查表程序。
二、需求分析基本要求:假设人名为中国姓名的汉语拼音模式。
待填入哈希表的人名共有30个,取平均查找长度的上限为2。
哈希函数用除留余数法构造,用链表法处理冲突。
测试数据:输入30个人的姓名拼音,即30个字符串,然后用除留余数法构建哈希表并用链表法处理冲突,最后将结果输出,程序自动计算查找长度的总数和平均查找长度,然后用户可以根据需求进行查找操作。
三、概要设计四、详细设计头文件#include <stdio. 30 *哈希表长度*int sum=0,k=0;typedef struct Node*哈希表结构体*{char key_code[10];*哈希表地址*struct Node *next;}Node;typedef struct mode;}void Hash_Init(HashTable str[0]+str[1]+str[2]; }int Hash_Insert(HashTable 1;}Node* Hash_Search(HashTable NULL;} else if( p;}p = p->next;sum++;}}return NULL;}int Hash_Create(HashTable ");return 1;}int ;i++){printf("%4d",i);printf("%4d",");}return count2;}void Hash_Link()*链表法构造函数*{int key;int i;Node *node;HashTable ",k); *查找总长度*printf("ASL=%d8\n",k); *平均查找长度*printf("请输入要查找的数据:");*输入查找的姓名*scanf("%s",&key);node = Hash_Search(",sum);if(node != NULL)printf("查找成功!");elseprintf("查找不成功!");}void -1;di++){address=((data%P)+di)%;if(status[address]==0){;}int 1;else{for(di=1;di<=-1;di++)*哈希表中元素与查找元素不相等,查找下一元素* {address=((key%P)+di)%;if( di+1;break;}}}if(di>=)return 0;}int main()*主函数*{printf("\t\t\t************************\n");printf("\t\t\t 哈希表设计\n");printf("\n");printf("\t\t\t************************\n");printf("\n");Hash_Link();}五、测试分析测试数据:随机输入的30个人的姓名拼音测试过程:输入30个人的姓名拼音,观察输出结果,并进行查找操作测试结果:主界面:哈希表:六、课程设计总结这次数据结构课程设计持续了两周,在这两周中付出了很多,同样也得到了很多。
哈希表的设置与实现
哈希表的设置与实现课程设计任务书设计题目:哈希表的设置与实现_________________________________________________________ 设计内容与要求:1.【问题描述】设计哈希表实现电话号码查询系统。
2.【基本要求】1、设每个记录有下列数据项:电话号码、用户名、地址;2、从键盘输入各记录,分别以电话号码和用户名为关键字建立哈希表;3、采用再哈希法解决冲突;4、查找并显示给定电话号码的记录;5、查找并显示给定用户名的记录。
6、在哈希函数确定的前提下,尝试各种不同类型处理冲突的方法(至少两种),考察平均查找长度的变化。
指导教师:2018年12月27日课程设计评语成绩:指导教师:年月日目录第1章需求分析 (3)1.1设计内容 (3)1.2数据需求 (3)1.3数据结构描述 (3)第2章概要设计 (4)2.1系统结构与模块功能 (4)2.2系统模块 (4)第3章详细设计与实现 (5)3.1模块流程图 (5)3.2界面效果图及代码 (7)3.3源代码 (11)第4章总结 (18)第1章需求分析1.1设计内容设计哈希表实现电话号码查询系统。
通过对姓名和电话号码构造哈希函数,接着根据姓名和号码进行查询,并计算它的平均查找长度。
并且尝试多种方法解决冲突,但至少使用两种方法来解决。
1.2数据需求1、设每个记录有下列数据项:电话号码、用户名、地址;2、从键盘输入各记录,分别以电话号码和用户名为关键字建立哈希表;3、采用再哈希法解决冲突;4、查找并显示给定电话号码的记录;5、查找并显示给定用户名的记录。
6、在哈希函数确定的前提下,尝试各种不同类型处理冲突的方法(至少两种),考察平均查找长度的变化。
1.3数据结构描述typedef struct Node{ char phone_num[12]; //电话号码char name[12]; //姓名char address[12]; //家庭住址struct Node *next, *next_; //后继指针}Node, *LinkNode;phone_num,name,address分别表示电话号码、姓名和家庭住址,next是name哈希链表的后继指针,next_是num哈希链表的后记指针。
数据结构设计报告--哈希查找与实现
数据结构课程设计报告书班级BX1001专业计算机科学与技术学号101003020139姓名赵冠博课题描述:哈希表的查找与实现分析1、 需求分析:本次课程设计需要实现哈希表的建立和查找,具体内容如下:建立哈希函数,从而根据用户输入的数据元素个数和各元素的值建立哈希表,即数据的添加和存储。
如果输入的元素个数超出规定范围,则打印出错信息,并提示重新输入信息。
哈希表建立好之后,用户可以输入想要查找的值,屏幕显示相应信息。
如果存在此值,屏幕显示该值信息;如果不存在,则显示该值不存在;如果想退出系统,则按提示输入命令。
2、 总体结构设计:1> 一个哈希表结构hashtable ,2>一个main ()主函数(完成数据输入和函数调用)、3>五个功能函数:Initialhash ()//初始化哈希表Printhash ()//输出哈希表的所有元素及其位置Searchhash ()//查找哈希表inserthash ()//查找哈希表deletehash ()//查找哈希表3、 各子模块设计:构成如下图所示:【设计思想】选取某个函数,依该函数按关键字计算元素的存储位置,并按此存放;查找时,由同一个函数对给定值kx 计算地址,将kx 与地址单元中元素关键字进行比较,确定查找是否成功,这就是哈希方法。
哈希方法中使用的转换函数称为Searchhash () Printhash () Initalhash() inserthash () deletehash哈希查找程序main()哈希函数。
程序首先通过插入操作建立哈希表,接着显示数据,然后运用哈希查找找到数据,如没有找到则显示查找错误,找到则显示查找成功。
4、编程实现:【实验程序主要代码】:#define MAXSIZE 12 //哈希表的最大容量,与所采用的哈希函数有关enum BOOL{False,True};enum HAVEORNOT{NULLKEY,HAVEKEY,DELKEY};//哈希表元素的三种状态,没有记录、有记录、有过记录但已被删除typedef struct //定义哈希表的结构{ int elem[MAXSIZE]; //数据元素体HAVEORNOT elemflag[MAXSIZE];//元素状态,没有记录、有记录、有过记录但已被删除 int count; // 哈希表中当前元素的个数}HashTable;typedef struct{ int keynum; // 记录的数据域,只有关键字一项}Record;void InitialHash(HashTable&); // 初始化哈希表void PrintHash(HashTable); // 显示哈希表中的所有元素BOOL SearchHash(HashTable,int,int&); // 在哈希表中查找元素BOOL InsertHash(HashTable&,Record); // 在哈希表中插入元素BOOL DeleteHash(HashTable&,Record); // 在哈希表中删除元素int Hash(int); // 哈希函数void main(){ HashTable H; // 声明哈希表Hchar ch,j='y';int position,n,k;Record R;BOOL temp;InitialHash(H);while(j!='n'){ printf("\n\t 哈希查找 ");printf("\n\t**************************************");printf("\n\t* 1-----建表 *");printf("\n\t* 2-----显示 *");printf("\n\t* 3-----查找 *");printf("\n\t* 4-----插入 *");printf("\n\t* 5-----删除 *");printf("\n\t* 0-----退出 *");printf("\n\t**************************************");printf("\n\n\t请输入菜单号:");scanf(" %c",&ch); // 输入操作选项switch(ch){ case '1':printf("\n请输入元素个数(<10): ");scanf("%d",&n);printf("\n");for( k=0;k<n;k++){ printf("请输入第%3d个整数: ",k+1);scanf("%d",&R.keynum); // 输入要插入的记录temp=InsertHash(H,R);};break;case '2':if(H.count) PrintHash(H); // 哈希表不空else printf("\n散列表为空表!\n");break;case '3':if(!H.count) printf("\n散列表为空表!\n"); // 哈希表空else{ printf("\n请你输入要查找元素(int) :");scanf("%d",&R.keynum); // 输入待查记录的关键字temp=SearchHash(H,R.keynum,position);// temp=True:记录查找成功;temp=False:没有找到待查记录if(temp) printf("\n查找成功该元素位置是 %d\n",position); else printf("\n本散列表没有该元素!\n");}break;case '4':if(H.count==MAXSIZE) // 哈希表已满 { printf("\n散列表已经满!\n");break; }printf("\n请输入要插入元素(int):");scanf("%d",&R.keynum); // 输入要插入的记录 temp=InsertHash(H,R);// temp=True:记录插入成功;temp=False:已存在关键字相同的记录if(temp) printf("\n元素插入成功!\n");else printf("\n元素插入失败,相同元素本散列表已经存在!\n"); break;case '5':printf("\n请你输入要删除元素(int):");scanf("%d",&R.keynum); // 输入要删除记录的关键字temp=DeleteHash(H,R);// temp=True:记录删除成功;temp=False:待删记录不存在if(temp) printf("\n删除成功!\n");else printf("\n删除元素不在散列表中!\n");break;default: j='n';}}printf("\n\t欢迎再次使用本程序,再见!\n");}void InitialHash(HashTable &H) // 哈希表初始化{ int i;H.count=0;for(i=0;i<MAXSIZE;i++) H.elemflag[i]=NULLKEY;}void PrintHash(HashTable H) // 显示哈希表所有元素及其所在位置{ int i;for(i=0;i<MAXSIZE;i++) printf("%-4d",i); // 显示哈希表中记录所在位置printf("\n");for(i=0;i<MAXSIZE;i++) // 显示哈希表中记录值if(H.elemflag[i]==HAVEKEY) printf("%-4d",H.elem[i]);else printf("%4c",' ');printf("\ncount:%d\n",H.count); // 显示哈希表当前记录数}BOOL SearchHash(HashTable H,int k,int &p){ // 在开放定址哈希表H中查找关键字为k的数据元素,若查找成功,以p指示待查//数据元素在表中的位置,并返回True;否则,以p指示插入位置,并返回Falseint p1;p1=p=Hash(k); // 求得哈希地址while(H.elemflag[p]==HAVEKEY&&k!=H.elem[p]) //该位置填有记录并且关键字不相等 { p++; // 冲突处理方法:线性探测再散列if(p>=MAXSIZE) p=p%MAXSIZE; // 循环搜索if(p==p1) return False; // 整个表已搜索完,没有找到待查元素 }if(k==H.elem[p]&&H.elemflag[p]==HAVEKEY) // 查找成功,p指示待查元素位置 return True;else return False; // 查找不成功}BOOL InsertHash(HashTable &H,Record e){ // 查找不成功时插入元素e到开放定址哈希表H中,并返回True,否则返回False int p;if(SearchHash(H,e.keynum,p)) // 表中已有与e有相同关键字的元素return False;else{ H.elemflag[p]=HAVEKEY; // 设置标志为HAVEKEY,表示该位置已有记录H.elem[p]=e.keynum; // 插入记录H.count++; // 哈希表当前长度加一return True;}}BOOL DeleteHash(HashTable &H,Record e){ // 在查找成功时删除待删元素e,并返回True,否则返回Falseint p;if(!SearchHash(H,e.keynum,p)) return False; // 表中不存在待删元素else{ H.elemflag[p]=DELKEY; // 设置标志为DELKEY,表明该元素已被删除 H.count--; // 哈希表当前长度减一return True;}}int Hash(int kn){ return (kn%11); } // 哈希函数:H(key)=key MOD 115、测试结果:【程序运行结果】建表和显示:查找:插入:删除:通过分析输入数据和运行结果,证明程序顺利完成实验内容和要求。
《哈希表》课程设计报告
《哈希表》课程设计报告数据结构散列表(哈希表)课程设计报告及源代码《哈希表的操作》设计报告一目的通过此次课程设计,让学生充分掌握对哈希表的有关操作,例如除留余数法的运用,处理冲突的三个办法:线性探测再散列,二次探测再散列,连地址法等。
加深学生对于哈希表这种独特存储方式(区别于线性存储和链式存储)的理解,和几种算法之间的优越性的体会。
二需求分析1、功能需求①.用户能够自定义输入单词,存入哈希表里;②.用户能够对当前哈希表进行管理。
操作内容包括:查看当前哈希表、搜索某个单词、插入任意单词、删除表中某个单词、查看当前表的平均搜索长度、置空当前哈希表。
③.程序有良好的交互界面,有操作提示和出错提示,方便用户使用和进出入程序。
2、程序约束①.哈希表的散列方法为除留余数法,处理冲突的办法为线性探测在散列。
②.使用C/C++语言编写,程序模块化设计。
三概要设计1、模块设计程序分为主程序模块和哈希表类定义模块,主程序存放在main.app中,哈希表类存放在HashTable.h头文件中。
①.主程序模块用于数据和DOS用户界面的初始化,主函数mai()内部定义子函数function(),调用哈希表类中的各个功能函数。
②.哈希表类定义Calculate(string s) 单词key值计算函数,类友元形参s传送输入的单词。
由于单词为string型,不方便直接拿来参与取余数计算,故用计算函数求出一个key来,同时可以减少冲突(字母相同的单词key有可能不同)。
FindPos(int key,string value) 地址查找函数,类成员key传送计算出的单词的关键值,value传送输入的单词,下同。
此函数为查找、插入、删除等函数提供地址搜索服务。
Search(int key,string value) 查找函数,类成员 Insert(string value) 插入函数,类成员 Remove(int key,string value) 删除函数,类成员 makeEmpty() 置空哈希表函数,类成员感谢您的阅读,祝您生活愉快。
哈希表的设计与实现课程设计报告
一: 需求分析 (2)三: 详细设计(含代码分析) (4)1. 程序描述: (4)2 具体步骤 (4)四调试分析和测试结果 (7)五,总结 (10)六. 参考文献; (11)七. 致谢 (11)八.附录 (11): 需求分析问题描述:设计哈希表实现电话号码查询系统。
基本要求1、设每个记录有下列数据项:电话号码、用户名、地址2、从键盘输入各记录,分别以电话号码和用户名为关键字建立哈希表;3、采用再哈希法解决冲突;4、查找并显示给定电话号码的记录;5、查找并显示给定用户名的记录。
6、在哈希函数确定的前提下,尝试各种不同类型处理冲突的方法(至少两种),考察平均查找长度的变化。
概要设计进入主函数,用户输入1或者2,进入分支选择结构:选1:以链式方法建立哈希表, 选2: 以再哈希的方法建立哈希表, 然后用户输入用户信息, 分别以上述确定的方法分别以用户名为检索以及以以电话号码为检索将用户信息添加到哈希表,. 当添加一定量的用户信息后, 用户接着输入用户名或者电话号码分别以用户名或者电话号码的方式从以用户名或电话号码为检索的哈希表查找用户信息. 程序用链表的方式存储信息以及构造哈希表。
具体流程图如下所示程序结束详细设计(含代码分析)1. 程序描述 :本程序以要求使用哈希表为工具快速快速查询学生信息,学生信息包括电话号 码、用户名、地址;用结构体存储struct node{ string phone; //string name; //string address;//node *next; //};2具体步骤1. 要求主要用在哈希法解决冲突, 并且至少尝试用两种方法解决冲突, 定义两 个指针数组存储信息 node *infor_phone[MAX]; node *infor_name[MAX]; 前者以电话号码为关键字检索哈希表中的信息, 后者以姓名为关键字检索哈希表中的 信息 用链式法和再哈希法解决冲突:int hash(string key) //{ //int result=1,cur=0,i; if(key.size()<=4) i=key.size()-1;else i=4;for(;i>=0;i--){ cur=key[i]-'0'; result=result*9+cur;}result%=(MOD); return result;}2. 得到输入信息的哈希码以后, 将相应的信息插入对应的地址, 若产生冲突, 则 循环到这个地址的最后一个节点, 然后再将节点插入到这个位置, 电话号码 姓名 地址 链接下一个地址的指以姓名或者电话号码的前四位运算结果作为哈 希码这样就避免了冲突, 在查找的时候便可直接找到这个地址然后快速的查找到信息:void add_infor_phone(string phone,string name,string address){int value=hash(phone);node *infor=build_infor(phone,name,address);if(infor_phone[value]==NULL)infor_phone[value]=infor;else{node *cur=infor_phone[value];while(cur->next)cur=cur->next;cur->next=infor;}}3. 再哈希法也是解决冲突的常见方法,当同义词产生地址冲突时计算另一个哈希函数地址,知道冲突不再发生,这种方法不易产生聚义,但是增加了计算时间:int hash_agin(int numble,int key) // 将关键字的前四位数经过计算的结果{ // 模上一个定义的数然后返回的数字为return numble%key; // 哈希码}int create(string key){int result=1,cur=0,i;if(key.size()<=4)i=key.size()-1;elsei=4;for(;i>=0;i--){ cur=key[i]-'0';result=result*9+cur;}return result;}4. 同样用链表为储存信息的数据结构,当产生冲突时,将模数减去一然后再寻找地址直到不再产生冲突:void add_infors(string phone,string name,string address){int numble_phone=create(phone),key=MOD,pos_phone,pos_name;while(infor_phone[pos_phone=hash_agin(numble_phone,key)]!=NULL) key--; key=MOD;int numble_name=create(name);while(infor_name[pos_name=hash_agin(numble_name,key)]!=NULL) key--; node *inforphone=new node;node *inforname=new node; inforphone->name=inforname->name=name; inforphone->phone=inforname->phone=phone;inforphone->address=inforname->address=address;inforphone->next=inforname->next=NULL; infor_phone[pos_phone]=inforphone; infor_name[pos_name]=inforname;5 . 帮主函数bool usersayyes() ,返回一个bool 值,要求用户输入一个正确的选项,减少程序因错误输入而出现的问题:bool usersayyes(){string sig;bool continu=true;cout<<" 请输入(N/n) 或(Y/y),(N/n) 代表退出,(Y/y) 代表继续:";while(cin>>sig&&(sig!="Y"&&sig!="y")&&(sig!="N"&&sig!="n")) cout<<" 输入错误, 请重新输入!"<<endl;return sig=="Y"||sig=="y";}四调试分析和测试结果1. 用链式法将用户信息添加到哈希表:2. 以姓名为关键字检索用户信息3. 当哈希表中不存在此项记录时4.再哈希法将用户信息添加到哈希表:5.以姓名为检索在哈希表中查找用户信息6. 以电话为检索在哈希表中查询信息使用哈希表能在较短的时间内查找出数据,程序的结果基本和理论相符合。
课程设计--哈希表查找算法的实现
学号:0121010340132课程设计题目哈希表查找算法的实现学院计算机科学与技术学院专业计算机科学与技术专业班级计算机1001班姓名指导教师2012 年 6 月27 日课程设计任务书题目: 哈希表查找算法的实现初始条件:理论:完成了《汇编语言程序设计》课程,对微机系统结构和80系列指令系统有了较深入的理解,已掌握了汇编语言程序设计的基本方法和技巧。
实践:完成了《汇编语言程序设计》的4个实验,熟悉了汇编语言程序的设计环境并掌握了汇编语言程序的调试方法。
要求完成的主要任务:(包括课程设计工作量及其技术要求,以及说明书撰写等具体要求)进一步理解和掌握较复杂程序的设计方法,掌握子程序结构的设计和友好用户界面的设计。
具体的设计任务及要求:1)输入一些整数,采用哈希表结构存储;2)实现对哈希表的查找;3)程序采用子程序结构,结构清晰;4)友好清晰的用户界面,能识别输入错误并控制错误的修改。
在完成设计任务后,按要求撰写课程设计说明书;对课程设计说明书的具体要求请见课程设计指导书。
阅读资料:1)《IBM—PC汇编语言程序设计实验教程》实验2.42)《IBM—PC汇编语言程序设计(第2版)》例6.11时间安排:设计安排一周:周1、周2:完成系统分析及设计。
周3、周4:完成程序调试,和验收。
周5:撰写课程设计报告。
指导教师签名:年月日系主任(或责任教师)签名:年月日目录⒈设计目的与任务 (4)⒈1问题描述 (4)⒈2设计目的 (4)⒈3测试用例 (5)⒉设计分析 (5)⒉1存储结构 (5)⒉2主要算法 (5)⒊设计步骤 (6)⒊1概要设计 (6)⒊2代码设计 (7)⒋调试分析和测试结果 (15)⒋1 编码分析 (15)⒋2 调试运行 (16)⒋3调试结果 (16)⒌心得体会 (17)⒍参考文献 (18)⒈设计目的与任务⒈1问题描述⒈⒈1题目:哈希表查找算法的实现⒈⒈2任务与要求:⑴输入一些整数,采用哈希表结构存储;⑵实现对哈希表的查找;⑶程序采用子程序结构,结构清晰;⑷友好清晰的用户界面,能识别输入错误并控制错误的修改。
(完整版)哈希表的设计与实现毕业设计
哈希表的设计与实现摘要哈希表的设计与实现是用Visual C++ 6.0编写的能够实现数据的存储,更新与查找的程序。
它可以方便的进行基本数据信息的输入(如:、电话、地址等),查询(按查询.按电话号查询),删除(运用删除),添加新的数据等。
易于管理员进行管理。
本设计使用Visual C++ 6.0开发工具利用其提供的各种面向对象的开发工具将数据信息定义在结构体中,运用类实现了对数据不同信息的操作功能。
关键字:哈希表; Visual C++ 6.0; 地址目录1、题目分析 .............................................................2、设计思路 .............................................................2.1问题描述......................................................2.2基本要求......................................................2.3数据结构......................................................3、设计思路 .............................................................4、测试的实验结果和测试过程..............................................4.1详细设计......................................................4.2屏幕截图......................................................4.3问题分析:....................................................5、课程设计体会及问题分析................................................6、参考文献 .............................................................7、源程序清单 ...........................................................1、题目分析在21世纪信息时代里,各个机构企业都需要处理一些庞大的重要的数据,而这些数据既需要随时查找还需要随时纪录新的数据。
哈希表课设报告
一、【问题描述】a)题目内容针对某个单位电话号码簿,设计一个哈希表,并完成相应的建表和查表程序。
b)基本要求1)假定每个记录有下列数据项:电话号码、用户名、地址。
2)以用户名和电话号码为关键字建立哈希表,哈希函数用除留取余数法构造,采用线性探测法解决冲突。
3)可以插入、查找、删除并显示给定用户名的记录,并计算查找长度。
哈希表保存到文件中。
4)哈希表保存到文件中。
二、【需求分析】a)软件的基本功能根据用户的选择,分别以姓名和电话号码做为关键字生成哈希表。
生成哈希表后用户可以根据相应关键字进行数据的查找,若查找到对应的数据则将数据输出到屏幕,在用户选择显示哈希表时,显示完整的哈希表。
b)输入/输出形式输入:自己打入姓名、电话号码、住址;数据的格式为:姓名、电话号码、住址或电话号码、姓名、地址。
输出:在用户需要时,将哈希表显示在屏幕上。
c)测试数据要求测试数据为字符串。
三、【概要设计】a)数据类型定义结构体类型存储每条记录。
struct fen //联系人信息结构体{string name;string add;string num;string phone;}st1,st2,b[100],b1[100];b)主程序流程及模块调用关系。
c)各函数功能void gotoxy(int x, int y)//控制坐标void Menu()//菜单void Menu1()//菜单void Create() //创建名字哈希表void Create1() //创建电话哈希表V oid allplay()//输出全部联系人V oid allplay1()//输出全部联系人void chazhao()//查找函数void chazhao1()//查找函数void choice()//选择函数void choice()1//选择函数void clean() //清空电话簿void clean()1 //清空电话簿void del()//删除单个联系人void del()1//删除单个联系人void fan()//泛查找函数void fan()1//泛查找函数void filename(int g)//向文件导入数据void filename1(int g)//向文件导入数据int H1(string k)//哈希取模函数int H1(string k)1//哈希取模函数void hash()//哈希查找函数(精确查找)void hash1()//哈希查找函数(精确查找)void jude()//判断是否有重复数据void jude()1//判断是否有重复数据int main()//主函数void putfile()//从文件读入数据void putfile1()//从文件读入数据四、【编码与调试分析】a)编码与调试过程中遇到的问题及解决的办法(1)在数据冲突的时候,不是向后在探查一位,而是直接覆盖了原有数据,这主要的问题出现在当时没有彻底理解线性探测算法,代码的先后有些问题使得后面的代码根本没有运行。
课程设计试验报告-哈希表的设计与实现
数据结构课程设计题目哈希表的设计与实现作者院系信息工程学院专业信息管理与信息系统学号1514210117指导老师张慧答辩时间2016年12月18日目录数据结构课程设计01系统需求分析11.1用户需求分析21.2功能需求分析21.3数据需求分析21.4 小结32系统设计32.1设计内容及要求32.2总体设计思路32.3程序详细设计流程图42.31以姓名为关键字的Hash()函数流程图42.32添加结点信息流程图:52.33按姓名查找流程图:62.34按号码查找流程图62.35主程序流程图72.4详细设计编码92.41建立节点92.42对哈希函数的定义92.43哈希查找92.44主函数103系统测试113.1上机调试113.2调试结果与分析114总结155附录151系统需求分析在信息化时代的今天,计算机技术已经是发展到一个很可观的地步了,特别是面向窗口的操作系统的出现,使得程序设计更加的容易了。
在过去计算机内存容量小,CPU计算速度慢,关于程序设计中的数据结构也因此提出来很多的关于解决这方面的问题。
哈希表就是其中之一,哈希表是一个由关键字与值组成的特殊的一种数据结构。
它的出现主要是为了解决在结构中查找记录时需要进行一系列和关键字的比较,这一类查找方法是建立在“比较”的基础上的,在顺序等的查找中,查找的效率是依赖于查找过程中所比较的次数。
理想的情况是希望不经过任何的比较一次存取便能得到所查记录,那就必须在记录的存储位置和它的关键字之间建立一个确定的对应关系,使得每个关键字和结构中一个唯一的存储位置相对应。
因而在查找时只要根据这个对应关系找到给定的值的像。
若结构中存在关键字和该值相等的记录,则所要查找的数就必定就是这个所查找到的记录。
哈希函数是建立哈希表的一个重要的成员,它的构造方法分为以下几种:直接定址法、数字分析法、平方取中法、折叠法、除留余数法、随机数法。
本程序中主要用的是除余取留法,除留取余法主要是取关键字被某个不大于哈希表表长m的数p出后所得余数为哈希地址即:H(key)=key MOD p, p<=m,这是一种最简单,也是一种最常用的构造函数的方法,它不仅可以对关键字直接取模,也可在折叠、平方中等运算之后取模。
(完整word版)哈希表《数据结构》课程设计
数学与计算机学院课程设计说明书课程名称: 数据结构-课程设计课程代码: 8404181题目:哈希表的设计与实现年级/专业/班: 2009级软件工程3班学生姓名:张加发学号:312009*********开始时间:2011 年06 月20 日完成时间:2011 年06 月29 日课程设计成绩:学习态度及平时成绩(30)技术水平与实际能力(20)创新(5)说明书撰写质量(45)总分(100)指导教师签名: 年月日数据结构课程设计任务书学院名称: 数学与计算机学院课程代码:8404181专业:软件工程年级:2009级一、设计题目哈希表的设计与实现二、主要内容设计哈希表实现电话号码查找系统,要求如下:1)设每个记录有下列数据项:电话号码、用户名、地址;2)从键盘输入各记录,分别以电话号码和用户名为关键字建立哈希表(要求设计两种以上不同的散列函数);3)采用两种以上的方法解决冲突;4)查找并显示给定电话号码的记录;5)查找并显示给定用户名的记录。
三、具体要求及应提交的材料1.每个同学以自己的学号和姓名建一个文件夹,如:“312009*********张三”。
里面应包括:学生按照课程设计的具体要求所开发的所有源程序(应该放到一个文件夹中)、任务书和课程设计说明书的电子文档。
2.打印的课程设计说明书(注意:在封面后夹入打印的“任务书”以后再装订)。
四、主要技术路线提示法、除留余数法等,解决冲突的方法也较多,常用:开放定址法、链地址法等。
五、进度安排共计两周时间,建议进度安排如下:选题,应该在上机实验之前完成需求分析、概要设计可分配4学时完成详细设计可分配4学时调试和分析可分配10学时.2学时的机动,可用于答辩及按教师要求修改课程设计说明书。
注:只用课内上机时间一般不能完成设计任务,所以需要学生自行安排时间做补充.六、推荐参考资料[1]苏仕华等编著,数据结构课程设计,机械工业出版社,2007[2]严蔚敏等编著,数据结构(C语言版),清华大学出版社,2003[3]严蔚敏等编著,数据结构题集(C语言版),清华大学出版社,2003指导教师签名日期年月日系主任审核日期年月日摘要分析了对线性表、栈、队列、字符串、树、图、查找、排序等理论知识的应用,对现实复杂问题的分析建模和解决方法!分析了针对系统的需求所要执行的解决方法的可行性,正确性.完成系统前需要进行问题描述、系统分析、设计建模、代码实现、调试修改,结果分析。
哈希表报告
哈希表设计题目哈希表设计[问题描述]针对自己的班集体中的“人名”设计一个哈希表,使得平均查找长度不超过R,完成相应的建表和查表程序。
[基本要求]假设人名为中国姓名的汉语拼音形式。
待填入哈希表的人名共有30个,取平均查找长度的上限为2。
构造哈希函数,用链表法处理冲突。
[测试数据]读取熟悉的30个人的姓名作测试。
一.需求分析:1. 针对自己的班集体中的“人名”设计一个哈希表,使得平均查找长度不超过R,完成相应的建表和查表程序。
2. 人名为中国姓名的汉语拼音形式。
待填入哈希表的人名共有30个,取平均查找长度的上限为2。
3. 用每个名字各个字符所对应的ASCII码相加,所得的整数做为哈希表的关键字,用除余法构造哈希函数,用拉链法处理冲突。
4.输入数据:zhaoxuening ,muchunyang ,lvzhihui,jiangbiwen,zhangye ,libaoling,yulin,wangjie,huangzheng,xiahaiyun,tanyongli,yangjiaqi,liufengbin,wangfeng,huangweilun,chenliang,hezhicong,yaochengzhong,chaozhihao,wangshipeng,ganyongze,luyang,baichongliang,zhurui,chenyiming,pengxuan,equanming,lishiwei,baitian,wuliao。
5.测试数据:lishiwei,zhurui,abcdefg,wangshipeng二.概要设计1.程序流程图2.存储结构:名字表:struct Name{ //名字表char *name; //名字int key; //关键码}哈希表:struct Node;typedef struct Node * PNode;struct Node{ //每条单链表结点结构定义char *name;PNode link;};struct HashDic{ //哈希表结构定义PNode llist[P]; //哈希表所包含的单链表,P为基本区域长度float search; //总查找长度float total; //哈希表中名字数int m; //哈希表长度};};typedef struct HashDic *PHashDic; //哈希表类型3.主要算法: (1). int h(char *py){ }//除余法,返回名字在哈希表中的相应地址(2) PHashDic create_EmptyDic(){ } //创建空哈希表(3)void insert_node(PHashDic phash,char *py) { } //插入算法(4)void search_node(PHashDic phash){ } //查找算法(5)void delete_node(PHashDic phash){ } //删除算法(6)void output_name(){ } //输出姓名表(7)void output_hash(PHashDic phd){ } //输出哈希表(8)void InitNameTable(){ } //姓名表的初始化(9)void print(){ } //打印操作菜单(10)void main(){ } //主函数三.详细设计1. 除余法,返回名字在哈希表中的相应地址int h(char *py){int key;for (int i=0;i<NAME_LEN;i++) //将字符串的各个字符所对应的ASCII码相加,所得的整数做为名字的关键字{int s=0;char *p=py;for (int j=0;*(p+j)!='\0';j++)s+=int(*(p+j));key=s;}return key%P;}2. 创建空哈希表PHashDic create_EmptyDic(){PHashDic phash=(PHashDic)malloc(sizeof(struct HashDic));int i;phash->search=0;phash->total=0;phash->m=P;for(i=0;i<phash->m;i++){phash->llist[i]=NULL;}return phash;}3. 插入算法void insert_node(PHashDic phash,char *py){PNode p,q;int r=1; //查找长度大于2的py的查找长度nt adr=h(py);if(phash->llist[adr]==NULL){ //如果单链表为空,向单链表插入第一个元素p=(PNode)malloc(sizeof(struct Node)); //创建新结点p->name=py;p->link=NULL;phash->llist[adr]=p;phash->total++;phash->search+=1;return;}q=phash->llist[adr];if (strcmp(q->name,py)==0) //如果已有此元素则不再插入{cout<<"名字已经存在"<<endl;return;}while (q->link!=NULL){if(strcmp(q->link->name,py==0{cout<<"名字已经存在"<<endl;return;}q=q->link;r++;}p=(PNode)malloc(sizeof(struct Node)); //否则就插入单链表最后p->name=py;p->link=NULL;q->link=p;r++;phash->search+=r;phash->total++;}4. 查找算法void search_node(PHashDic phash){PNode p;int adr,r; //哈希表地址和查找长度char py[20];cout<<"请输入要查找的名字:\n";cin>>py;adr=h(py);if(phash->llist[adr]==NULL) cout<<"查找结果:\n"<<"没有想要查找的人!!\n";//如果相应单链表为空,则没有所要查找的名字else {p=phash->llist[adr];while(strcmp(p->name,py)!=0 && p->link!=NULL)//否则对比单链表内容直到查找到名字或对比完单链表中数据{p=p->link;r++;}if(strcmp(p->name,py)==0)cout<<"查找结果:\n"<<"名字:"<<py<<" 地址"<<adr<<" 查找长度"<<r<<endl;//查找到名字else cout<<"查找结果:\n"<<"没有想要查找的人\n"; //对比完单链表中数据,没有该名字}}5. 删除算法void delete_node(PHashDic phash){PNode p,q;int r=1; //查找长度char py[20]={0};cout<<"请输入要删除的名字:\n";cin>>py;int adr=h(py);if(phash->llist[adr]==NULL) //如果相应单链表为空,则没有所要删除的名字{cout<<"没有想要删除的名字!!\n";return;}p=phash->llist[adr];if(strcmp(p->name,py)==0) //如果要删除的是单链表第一个元素{phash->llist[adr]=p->link;free(p);cout<<"删除完成!!\n";phash->total--;phash->search-=1;return;}while(p->link!=NULL && strcmp(p->link->name,py)!=0 )//否则对比单链表内容直到查找到名字或对比完单链表中数据{p=p->link;}if(strcmp(p->link->name,py)==0) //查找到名字{q=p->link;p->link=q->link;free(q);cout<<"删除完成!!\n";r++;phash->search-=r;phash->total--;return;}else //对比完单链表中数据,没有该名字{cout<<"没有想要删除的名字!!\n";return;}}6. //输出姓名表void output_name(){ //输出姓名表int i;printf("序号\t\t 姓名\t\t 关键字\n");for (i=0;i<NAME_LEN;i++)printf("%2d %18s \t\t %d \n",i,NameTable[i].name,NameTable[i].key); }7.输出哈希表void output_hash(PHashDic phd){ //输出哈希表PNode p;float ASL; //平均查找长度nt i;cout<<"地址名字\n";for (i=0;i<P;i++){p=phd->llist[i];cout<<i;while(p!=NULL){cout<<" 一> "<<p->name;p=p->link;}cout<<endl;}ASL=phd->search/phd->total;cout<<"平均查找长度:"<<ASL<<endl;}8. 姓名表的初始化void InitNameTable(){NameTable[0].name="zhaoxuening";NameTable[1].name="muchunyang";NameTable[2].name="lvzhihui";NameTable[3].name="jiangbiwen";NameTable[4].name="zhangye";NameTable[5].name="libaoling";NameTable[6].name="yulin";NameTable[7].name="wangjie";NameTable[8].name="huangzheng";NameTable[9].name="xiahaiyun";NameTable[10].name="tanyongli";NameTable[11].name="yangjiaqi";NameTable[12].name="liufengbin";NameTable[13].name="wangfeng";NameTable[14].name="huangweilun";NameTable[15].name="chenliang";NameTable[16].name="hezhicong";NameTable[17].name="yaochengzhong";NameTable[18].name="chaozhihao";NameTable[19].name="wangshipeng";NameTable[20].name="ganyongze";NameTable[21].name="luyang";NameTable[22].name="baichongliang";NameTable[23].name="zhurui";NameTable[24].name="chenyiming";NameTable[25].name="pengxuan";NameTable[26].name="equanming";NameTable[27].name="lishiwei";NameTable[28].name="baitian";NameTable[29].name="wuliao";for (int i=0;i<NAME_LEN;i++)//将字符串的各个字符所对应的ASCII码相加,所得的整数做为名字的关键字{int s=0;for (int j=0;NameTable[i].name[j]!='\0';j++)s+=int(NameTable[i].name[j]);NameTable[i].key=s;}}9. 打印操作菜单void print(){cout<<" ********************************************************\n";cout<<" 操作菜单\n";cout<<" 1.输出姓名表\n";cout<<" 2.输出哈希表\n";cout<<" 3.查找\n";cout<<" 4.删除\n";cout<<" 5.插入\n";cout<<" 6.退出\n";cout<<" ********************************************************\n"; }10.主函数void main(){int i,c,k=0;PHashDic phash=create_EmptyDic(); //创建空哈希表phashInitNameTable();for (i=0;i<NAME_LEN;i++) //将名字表中的名字存入哈希表insert_node(phash,NameTable[i].name);print(); //打印操作菜单cout<<"请选择操作:";cin>>c;while(c!=1&&c!=2&&c!=3&&c!=4&&c!=5&&c!=6) {cout<<"请重新选择操作:";cin>>c;}do{//当选择6时结束算法,选择1,2,3,4,5则执行相应操作直到结束switch(c){case 1:output_name();print();break; //输出姓名表case 2: output_hash(phash);print();break; //输出哈希表case 3:search_node(phash);print();break; //查找case 4:delete_node(phash);print();break; //删除case 5:{char py[20]; //插入cout<<"请输入要插入的名字:\n";cin>>py;insert_node(phash,py);}print();break;case 6:cout<<"已退出\n";break;default:cout<<"\n请输入正确的选择!\n:";}if(c!=6){cout<<"请选择操作:";cin>>c;while(c!=1&&c!=2&&c!=3&&c!=4&&c!=5&&c!=6){cout<<"请重新选择操作:";cin>>c;}}}while (c==1||c==2||c==3||c==4||c==5); }四.调试分析1.输出姓名表2.输出哈希表3.查找:lishiwei和abcdefg4.删除:lishiwei,zhurui,abcdefg5.插入:abcdefg和wangshipeng6.退出五.课程设计总结算法分析及改进:1. 由于要对哈希表进行插入,删除等操作字典元素处于动态,而且名字出现无规律可言,因此采用除余法构造哈希函数h(x) = x mod P 。
哈希查找的实现与分析报告(顺序).docx
目录1 课程设计内容 (1)1.1课程设计目的 (1)1.2课程设计要求 (1)1.3课程设计背景 (1)2 概要设计 (2)2.1程序模块结构图 (2)2.2主界面模块说明 (2)2.3读取学生信息模块说明 (2)3 详细设计 (3)3.1建立哈希表 (3)3.2计算哈希值 (3)3.3读取文件 (4)3.4显示所有学生信息 (6)3.5查找学生信息 (7)3.6界面显示 (9)3.7主函数 (10)4 问题与解决 (12)小结 (13)参考文献 (13)1 课程设计内容1.1 课程设计目的课程设计题目:哈希查找的实现与分析(1)掌握哈希函数的构造原则及哈希表的生成方法,并能在解决实际问题时灵活应用。
(2)掌握哈希查找的基本过程及其适用场合。
(3)巩固在散列查找时解决冲突的方法,并比较各种方法的特点。
(4)掌握平均查找长度ASL的计算方法。
1.2 课程设计要求程序要求实现的功能有:(1)所有数据从文本文件Hash.txt中读取。
(2)根据实际问题自行构造合理的哈希函数,要求采用开放定址法或拉链法,解决Hash 表的冲突。
(3)严格按照哈希表构造的一般原则进行编程(不能简单地将文件中的数据读到一个数组里,再从数组里完成相应的查找功能)。
(4)计算该哈希表查找成功时的ASL,并在课设报告中给出具体分析过程。
(5)如果一个班级中有两个同学抽中此题,则要求学号在前面的同学用拉链法,学号在后面的同学用开放定址法来解决冲突。
1.3 课程设计背景哈希查找的产生有这样一种背景——有些数据本身是无法排序的(如图像),有些数据是很难比较的(如图像)。
如果数据本身是无法排序的,就不能对它们进行比较查找。
如果数据是很难比较的,即使采用折半查找,要比较的次数也是非常多的。
因此,哈希查找并不查找数据本身,而是先将数据映射为一个整数(它的哈希值),并将哈希值相同的数据存放在同一个位置一即以哈希值为索引构造一个数组。
在哈希查找的过程中,只需先将要查找的数据映射为它的哈希值,然后查找具有这个哈希值的数据,这就大大减少了查找次数。
课程设计报告--数据哈希表应用
课程设计报告--数据哈希表应用兰州商学院陇桥学院工学系课程设计报告设计题目:数据哈希表应用系别:工学系专业 (方向):网络工程班年级、班:2012级计算机科学与技术学生姓名:李妮学生学号:20120661116指导教师:王万玉2013年12 月24 日目录二、需求分析: 0三、算法思想: 0四、概要设计: (1)五.系统的设计与实现 (1)六、总结 (3)七、附件(代码、部分图表) (4)哈希表应用一、问题描述哈希表应用设计:设哈希表长为13,用除留余数法构造一个哈希函数,以开放定址法中的线性探测再散列法作为解决冲突的方法,编程实现哈希表的查找、插入、删除、显示和退出系统的算法。
二、需求分析:1、功能需求①.用户能够自定义输入数据,存入哈希表里;②.用户能够对当前哈希表进行管理。
操作内容包括:显示当前哈希表、查询某个数据、插入某个数据、删除表中某个数据、退出该系统。
③.程序有良好的交互界面,有操作提示和出错提示,方便用户使用和进出入程序。
2、程序约束①.哈希表的散列方法为除留余数法,处理冲突的办法为线性探测在散列。
②.使用C/C++语言编写,程序模块化设计。
程序可实现用户与计算机的交互过程。
在计算机显示提示信息后,可由用户键入运算命令以实现对应的功能,包含表的建立、数据的查找、插入、删除、显示、退出等功能。
本程序旨在实现哈希函数的构造与处理存储冲突,因而指定哈希表存储的数据类型为简单的整型数字,在实用性上还有所欠缺。
但根据用户需求的变化,可以对程序的基本数据类型进行改造,以实现更为丰富的功能,进而体现哈希表在查找数据时的优越性。
三、算法思想:在设定哈希表的抽象数据类型时,要有查找数据元素的操作。
另外,插入操作和删除操作也要用到查找数据元素操作,以查看该数据元素是否存在,因此可以设计查找元素操作包括插入和删除操作的查找。
因此,查找操作就有两种情况:一种情况是插入操作时寻找空闲单元的查找;另一种情况是在查找和删除操作时寻找该元素是否在哈希表中已存在的查找。
哈希表的实验报告
哈希表的实验报告哈希表的实验报告哈希表是一种常见的数据结构,用于存储和查找数据。
在本次实验中,我们将探索哈希表的原理、实现和性能,并通过实验验证其效果。
一、实验目的本次实验的目的是探索哈希表的原理和实现方法,并通过实验测试不同哈希函数和哈希表大小对性能的影响。
二、实验原理哈希表是一种基于哈希函数的数据结构,它将数据存储在数组中,通过哈希函数将数据映射到数组的特定位置。
哈希函数将数据转换为数组的索引,使得数据可以快速存储和查找。
哈希函数的选择很重要,一个好的哈希函数应该具备以下特点:1. 均匀性:哈希函数应该将数据均匀地分布到不同的索引位置,以避免冲突。
2. 高效性:哈希函数应该具有高效的计算速度,以提高哈希表的性能。
3. 低冲突:哈希函数应该尽可能减少冲突的发生,以提高哈希表的查找效率。
三、实验方法1. 实现哈希表:我们首先需要实现一个基本的哈希表数据结构。
哈希表可以使用数组来存储数据,每个数组元素称为一个桶,每个桶可以存储多个数据项。
在实现哈希表时,我们需要考虑如何处理冲突,常见的方法有链地址法和开放地址法。
2. 实现哈希函数:我们需要实现不同的哈希函数,以测试它们的性能。
常见的哈希函数包括除余法、乘法和平方取中法等。
我们可以通过实验比较它们的性能,选择最合适的哈希函数。
3. 测试性能:我们需要设计一系列实验,测试不同哈希函数和哈希表大小对性能的影响。
可以通过插入、查找和删除等操作来评估哈希表的性能。
我们可以记录每个操作的平均时间复杂度和空间占用情况,并绘制图表来展示结果。
四、实验结果与分析通过实验,我们得到了不同哈希函数和哈希表大小下的性能数据。
我们可以观察到不同哈希函数对性能的影响,并选择最优的哈希函数。
同时,我们还可以观察到哈希表大小对性能的影响,选择合适的哈希表大小以平衡性能和空间占用。
五、实验总结本次实验我们深入了解了哈希表的原理和实现方法,并通过实验验证了不同哈希函数和哈希表大小对性能的影响。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一: 需求分析 (2)三: 详细设计(含代码分析) (4)1.程序描述: (4)2具体步骤 (4)四调试分析和测试结果 (7)五,总结 (9)六.参考文献; (10)七.致谢 (10)八.附录 (11)一: 需求分析问题描述:设计哈希表实现电话号码查询系统。
基本要求1、设每个记录有下列数据项:电话号码、用户名、地址2、从键盘输入各记录,分别以电话号码和用户名为关键字建立哈希表;3、采用再哈希法解决冲突;4、查找并显示给定电话号码的记录;5、查找并显示给定用户名的记录。
6、在哈希函数确定的前提下,尝试各种不同类型处理冲突的方法(至少两种),考察平均查找长度的变化。
二: 概要设计进入主函数,用户输入1或者2,进入分支选择结构:选1:以链式方法建立哈希表,选2:以再哈希的方法建立哈希表,然后用户输入用户信息,分别以上述确定的方法分别以用户名为检索以及以以电话号码为检索将用户信息添加到哈希表,.当添加一定量的用户信息后,用户接着输入用户名或者电话号码分别以用户名或者电话号码的方式从以用户名或电话号码为检索的哈希表查找用户信息.程序用链表的方式存储信息以及构造哈希表。
具体流程图如下所示:三: 详细设计(含代码分析)1.程序描述:本程序以要求使用哈希表为工具快速快速查询学生信息,学生信息包括电话号码、用户名、地址;用结构体存储struct node{ string phone; //电话号码string name; //姓名string address;//地址node *next; //链接下一个地址的指针};2具体步骤1. 要求主要用在哈希法解决冲突,并且至少尝试用两种方法解决冲突,定义两个指针数组存储信息node *infor_phone[MAX]; node *infor_name[MAX];前者以电话号码为关键字检索哈希表中的信息,后者以姓名为关键字检索哈希表中的信息用链式法和再哈希法解决冲突:int hash(string key) //以姓名或者电话号码的前四位运算结果作为哈{ //希码int result=1,cur=0,i;if(key.size()<=4)i=key.size()-1;else i=4;for(;i>=0;i--){cur=key[i]-'0';result=result*9+cur;}result%=(MOD);return result;}2.得到输入信息的哈希码以后,将相应的信息插入对应的地址,若产生冲突,则循环到这个地址的最后一个节点,然后再将节点插入到这个位置,这样就避免了冲突,在查找的时候便可直接找到这个地址然后快速的查找到信息:void add_infor_phone(string phone,string name,string address){int value=hash(phone);node *infor=build_infor(phone,name,address);if(infor_phone[value]==NULL)infor_phone[value]=infor;else{node *cur=infor_phone[value];while(cur->next)cur=cur->next;cur->next=infor;}}3. 再哈希法也是解决冲突的常见方法,当同义词产生地址冲突时计算另一个哈希函数地址,知道冲突不再发生,这种方法不易产生聚义,但是增加了计算时间:int hash_agin(int numble,int key) //将关键字的前四位数经过计算的结果{ //模上一个定义的数然后返回的数字为 return numble%key; //哈希码}int create(string key){int result=1,cur=0,i;if(key.size()<=4)i=key.size()-1;elsei=4;for(;i>=0;i--){cur=key[i]-'0';result=result*9+cur;}return result;}4. 同样用链表为储存信息的数据结构,当产生冲突时,将模数减去一然后再寻找地址直到不再产生冲突:void add_infors(string phone,string name,string address){int numble_phone=create(phone),key=MOD,pos_phone,pos_name;while(infor_phone[pos_phone=hash_agin(numble_phone,key)]!=NULL) key--;key=MOD;int numble_name=create(name);while(infor_name[pos_name=hash_agin(numble_name,key)]!=NULL)key--;node *inforphone=new node;node *inforname=new node;inforphone->name=inforname->name=name;inforphone->phone=inforname->phone=phone;inforphone->address=inforname->address=address;inforphone->next=inforname->next=NULL;infor_phone[pos_phone]=inforphone;infor_name[pos_name]=inforname;}5 .帮主函数bool usersayyes(),返回一个bool值,要求用户输入一个正确的选项,减少程序因错误输入而出现的问题:bool usersayyes(){string sig;bool continu=true;cout<<"请输入(N/n)或(Y/y),(N/n)代表退出,(Y/y)代表继续:";while(cin>>sig&&(sig!="Y"&&sig!="y")&&(sig!="N"&&sig!="n")) cout<<"输入错误,请重新输入!"<<endl;return sig=="Y"||sig=="y";}四调试分析和测试结果1.用链式法将用户信息添加到哈希表:2.以姓名为关键字检索用户信息:3.当哈希表中不存在此项记录时: 4.再哈希法将用户信息添加到哈希表:5.以姓名为检索在哈希表中查找用户信息:6.以电话为检索在哈希表中查询信息:使用哈希表能在较短的时间内查找出数据,程序的结果基本和理论相符合。
五,总结通过做这个课程设计,使我们对如何去解决分析一个没有接触过的问题有深刻的认识,我们开始对题目有很多误解,根本没有思路,经过老师的几次讲解和我们自己很多的讨论,最终把问题进行转换,老师的要求是为了一个映射关系,我们找到了一个算法,算法和公式是可以相互转换的,在这个过程我们发现自己的程序有很多问题,经过我们不断对算法进行修改使得我们的程序运行的更快。
哈希表的设计与实现这一算法始终围绕怎样解决冲突和怎样快速查找数据为目的,要求用在哈希法和链式法设计和实现哈希表,经过查阅资料请教同学问题渐渐的变得清晰,在分析问题,思考问题和解决问题的过程中,很大程度上培养了我们的动手和动脑的能力,开始选择一个合适的数据结构,然后依据算法编码,调试,最后得出正确结论,整个过程虽然遇到了很多问题,特别是指针的冲突,这样在不知不觉中培养了我的耐性,“数据结构与算法”课程是计算机专业的一门十分重要的核心基础课程。
这次的课程设计,,拓广了我解决实际问题的程序设计的思路,也培养了对于问题进行深入探究的习惯。
我更加深刻的体会到各种路由算法的特点,以及性能的优劣。
为我今后专业课程的学习奠定了坚实的理论基础!六.参考文献;1. 数据结构严蔚敏,吴伟明(c语言版)清华大学出版社2. 算法导论Thoms.H.Cormen , Charles E.Leiserson , Ronald L.Rivest, Clifford Stein著潘金贵,顾铁成,李成法译第二版机械工业出版社3. 数据结构基础(C语言版)(第2版) Ellis Horowitz,Sartaj Sahni,Susan Anderson-Freed著朱仲涛译清华大学出版社4. 数据结构与算法分析:C语言描述(英文版.第2版) Mark Allen Weiss 著机械工业出版社5. 算法之道邹恒明(第2版) 机械工业出版社七.致谢在这次课程设计的撰写过程中,我得到了许多人的帮助。
首先我要感谢我的老师在课程设计上给予我的指导、提供给我的支持和帮助,这是我能顺利完成这次报告的主要原因,更重要的是老师帮我解决了许多技术上的难题,让我能把系统做得更加完善。
在此期间,我不仅学到了许多新的知识,而且也开阔了视野,提高了自己的设计能力。
其次,我要感谢帮助过我的同学,他们也为我解决了不少我不太明白的设计商的难题。
同时也感谢学院为我提供良好的做毕业设计的环境。
最后再一次感谢所有在设计中曾经帮助过我的良师益友和同学八.附录#include<iostream>#include<string>using namespace std;#define MAX 10000#define MOD 9873struct node //定义储存学生信息的结构体{string phone;string name;string address;node *next;};node *infor_phone[MAX]; //存放信息的指针数组node *infor_name[MAX];void init() //初始化初始化指针数组{for(int i=0;i<MAX;i++){infor_phone[i]=NULL;infor_name[i]=NULL;}}bool usersayyes() //帮助函数要求用户输入正确的选项{string sig;bool continu=true;cout<<"请输入(N/n)或(Y/y),(N/n)代表退出,(Y/y)代表继续:";while(cin>>sig&&(sig!="Y"&&sig!="y")&&(sig!="N"&&sig!="n")) cout<<"输入错误,请重新输入!"<<endl;return sig=="Y"||sig=="y";}//再哈希法int hash_agin(int numble,int key) //再哈希法获得地址的函数{return numble%key;}int create(string key){int result=1,cur=0,i;if(key.size()<=4)i=key.size()-1;elsei=4;for(;i>=0;i--){cur=key[i]-'0';result=result*9+cur;}return result;}void add_infors(string phone,string name,string address)//再希法添//加用户信息到哈希表{int numble_phone=create(phone),key=MOD,pos_phone,pos_name; while(infor_phone[pos_phone=hash_agin(numble_phone,key)]!=NULL)key--;key=MOD;int numble_name=create(name);while(infor_name[pos_name=hash_agin(numble_name,key)]!=NULL) key--;node *inforphone=new node;node *inforname=new node;inforphone->name=inforname->name=name;inforphone->phone=inforname->phone=phone;inforphone->address=inforname->address=address;inforphone->next=inforname->next=NULL;infor_phone[pos_phone]=inforphone;infor_name[pos_name]=inforname;}void find_byname(string name) //以名字为关键字查询用户信息{int numble_name=create(name),key=MOD,pos_name;while(true){pos_name=hash_agin(numble_name,key);if(infor_name[pos_name]==NULL){cout<<"不存在你要查找的信息!"<<endl;cout<<"-------------------------------------------"<<endl;return;}if(infor_name[pos_name]->name==name){cout<<infor_name[pos_name]->name<<endl;cout<<"电话:";cout<<infor_name[pos_name]->phone<<endl;cout<<"地址:";cout<<infor_name[pos_name]->address<<endl;cout<<"-------------------------------------------"<<endl;return ;}key--;}}void find_byphone(string phone) //以电话为关键字查询用户信息{int numble_phone=create(phone),key=MOD,pos_phone;while(true){pos_phone=hash_agin(numble_phone,key);if(infor_phone[pos_phone]==NULL){cout<<"不存在你要查找的信息!"<<endl;cout<<"-------------------------------------------"<<endl;return;}if(infor_phone[pos_phone]->phone==phone){cout<<infor_phone[pos_phone]->name<<endl;cout<<"电话:";cout<<infor_phone[pos_phone]->phone<<endl;cout<<"地址:";cout<<infor_phone[pos_phone]->address<<endl;cout<<"-------------------------------------------"<<endl;return ;}key--;}}void find(){string sig,infor;cout<<"请输入(1)或(2),(1)代表姓名,(2)代表电话:";while(cin>>sig&&(sig!="1"&&sig!="2"))cout<<"输入错误,请重新输入!"<<endl;cout<<"请输入要查找的信息:";cin>>infor;if(sig=="1")find_byname(infor);elsefind_byphone(infor);}//链表法int hash(string key) //链表法获得哈希码{int result=1,cur=0,i;if(key.size()<=4)i=key.size()-1;elsei=4;for(;i>=0;i--){cur=key[i]-'0';result=result*9+cur;}result%=(MOD);return result;}node * build_infor(string phone,string name,string address) { //存储用户信息到哈希表node *information=new node;information->phone=phone;information->name=name;information->address=address;information->next=NULL;return information;}void add_infor_phone(string phone,string name,string address) {int value=hash(phone);node *infor=build_infor(phone,name,address);if(infor_phone[value]==NULL)infor_phone[value]=infor;else{node *cur=infor_phone[value];while(cur->next)cur=cur->next;cur->next=infor;}}void add_infor_name(string phone,string name,string address){int value=hash(name);node *infor=build_infor(phone,name,address);if(infor_name[value]==NULL)infor_name[value]=infor;else{node *cur=infor_name[value];while(cur->next)cur=cur->next;cur->next=infor;}}void findinfor() //分别以名字和电话为关键字查询用户信息{string infor;int sig,pos;cout<<"请输入要供查找的信息代号:1代表电话号码,2代表姓名:";while(cin>>sig&&(sig!=1&&sig!=2))cout<<"输入错误,请重新输入!"<<endl;cout<<"请输入要供查找的信息:";cin>>infor;if(sig==1){bool flag=true;pos=hash(infor);node * cur=infor_phone[pos];while(cur){if(cur->phone==infor){cout<<"姓名:"<<cur->name<<endl;cout<<"电话:"<<cur->phone<<endl;cout<<"地址:"<<cur->address<<endl;flag=false;break;}cur=cur->next;}if(flag)cout<<"不存在要查找的记录!"<<endl;cout<<"-------------------------------------------"<<endl;}else if(sig==2){bool flag=true;pos=hash(infor);node * cur=infor_name[pos];while(cur){if(cur->name==infor){cout<<"姓名:"<<cur->name<<endl<<"电话:"<<cur->phone<<endl<<"地址:"<<cur->address<<endl;flag=false;break;}cur=cur->next;}if(flag)cout<<"不存在要查找的记录!"<<endl;cout<<"--------------------------------------"<<endl;}else{cout<<"输入错误,请重新输入:"<<endl;cout<<"--------------------------------------"<<endl; findinfor();}}void hash_frist(){int numble;string phone,name,address,sig;init();cout<<"请输入添加的人数:";cin>>numble;while(numble--){cout<<"请输入----姓名:";cin>>name;cout<<"请输入电话号码:";cin>>phone;cout<<"请输入----地址:";cin>>address;cout<<"--------------------------------------"<<endl; add_infor_phone(phone,name,address);add_infor_name(phone,name,address);}do findinfor();while(usersayyes());}void hash_second(){int numble;string phone,name,address,sig,infor;init();cout<<"请输入添加的人数:";cin>>numble;while(numble--){cout<<"请输入----姓名:";cin>>name;cout<<"请输入电话号码:";cin>>phone;cout<<"请输入----地址:";cin>>address;cout<<"--------------------------------------"<<endl; add_infors(phone,name,address);}do find();while(usersayyes());}int main() //主函数{string chois;cout<<"请输入(1)或(2)--(1)链式法(2)再哈希:";while(cin>>chois&&(chois!="1"&&chois!="2"))cout<<"输入错误,请重新输入!"<<endl;if(chois=="1")hash_frist();if(chois=="2")hash_second();return 0;}。