哈希表的设计与实现 课程设计报告

合集下载

哈希表课程设计报告

哈希表课程设计报告

哈希表设计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世纪信息时代里,各个机构企业都需要处理一些庞大的重要的数据,而这些数据既需要随时查找还需要随时纪录新的数据。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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;}。

相关文档
最新文档