散列表实验报告doc

合集下载

散列查找顺序表的实现实验报告

散列查找顺序表的实现实验报告

题目:顺序表的实现一、实验题目顺序表的实现二、实验目的⑴掌握线性表的顺序存储结构;⑵验证顺序表及其基本操作的实现;⑶理解算法与程序的关系,能够将顺序表算法转换为对应的程序。

三、实验内容与实现⑴建立含有若干个元素的顺序表;⑵对已建立的顺序表实现插入、删除、查找等基本操作。

实验实现#include<stdio.h>#include<memory.h>int a[10000];int arrlong(){int j;for(j=0;j<12;j++)if(a[j]==0)break;return j;}int Insect(int n,int s) ////插入{int j;for(j=0;j<10000;j++)if(a[j]==0)break;printf("要操作的元素\n");for(int i=0;i<j;i++)printf("%d ",a[i]);printf("\n");for(int i=j;i>n-1;i--)a[i+1]=a[i];a[n]=s;for(int k=0;k<j+1;k++)printf("%d ",a[k]);printf("\n");}int Search(int p) //查找{int j,h;for(j=0;j<12;j++){if(a[j]==0)break;}for(h=0;h<j;h++){if(a[h]==p){printf("查找到的数在第%d位\n",h+1);break;}}if(h==j)printf("查无此数\n");}int Delate(int g,int q) //删除{int j;g=g-1;for(int j=g;j<12;j++)a[j]=a[j+1];for(q =0;q<12;q++){if(a[q]==0)break;}for(int i=0;i<q;i++)printf("%d ",a[i]);printf("\n");}int main(){int y,c;printf(" 菜单\n");printf("-------------------------------------------------\n");printf("0 建表\n1 插入\n2 查找\n3 删除\n4 退出\n");printf("-------------------------------------------------\n");while(scanf("%d",&y)!=EOF){int n,x,s;if(y==0){memset(a,0,sizeof(a));printf("请输入元素的个数:\n");scanf("%d",&c);printf("请输入数据:\n");for(int i = 0;i < c;i++)scanf("%d",&a[i]);}else if(y==1){int L;printf("请输入插入的第几位\n");scanf("%d",&n);//输入L=arrlong();if(n<=L){printf("请输入插入的数字\n");scanf("%d",&s);Insect(n,s);}else{printf("输入有误\n");continue;}}else if(y==2){int p;printf("请输入要查找的数字\n");scanf("%d",&p);Search(p);}else if(y==3){int g,q,L;printf("请输入要删除数的位置\n");scanf("%d",&g);L=arrlong();if(L>=g){Delate(g,q);}else{printf("输入有误\n");printf(" 菜单\n");printf("-------------------------------------------------\n");printf("0 建表\n1 插入\n2 查找\n3 删除\n4 退出\n");printf("-------------------------------------------------\n");continue;}}else if(y==4)break;else{printf("输入有误\n");printf(" 菜单\n");printf("-------------------------------------------------\n");printf("0 建表\n1 插入\n2 查找\n3 删除\n4 退出\n");printf("-------------------------------------------------\n");continue;}printf(" 菜单\n");printf("-------------------------------------------------\n");printf("0 建表\n1 插入\n2 查找\n3 删除\n4 退出\n");printf("-------------------------------------------------\n");}}建立顺序表:插入操作:查找操作:删除操作:插入数据超出顺序表范围:查找不到输入数据:删除数据超出顺序表范围:四、实验心得1.掌握了为数组赋值的方法,深刻理解了数组的含义2.掌握了为数组排序的方法。

山东大学-数据结构实验报告-矩阵和散列表

山东大学-数据结构实验报告-矩阵和散列表

山东大学计算机科学与技术学院数据结构课程实验报告了Input函数和Output函数。

对问题三,仿课本所述,定义Term类作为SparseMatrix类的友元类,包含行、列、值三个要素的成员变量,用Term类的数组实现稀疏矩阵的行主映射存储。

查找行为的实现方式是,找到位于目标元素前一行的最后一个元素,再从这个元素开始向下搜索,直到找到和目标元素同一行但是列数小于目标元素的元素a[k-1],然后决定下一步的行为————插入一个新项Term作为a[k]并将已有元素向后移位,还是修改已存在的项a[k]。

以此原理编写了Store和Retrieve函数,并扩展编写了Input函数和Output函数。

对问题四,仿照课本例子编写了有序链表类SortedChain、开放寻址的散列表类HashTable、基于有序链表链接的散列表类ChainHashTable,并对这三个类分别扩展编写了Output函数。

3.测试结果(测试输入,测试输出)问题一:问题二:上图显示了输入不符合下三角方阵约束时,抛出异常并退出程序。

上图是正常运行的结果。

问题三:普通的输入和输出操作如下:矩阵相加:矩阵转置:问题四:以上图的数据为例。

从346就应该在链表链接的散列表上看到开放寻址解决冲突的例子。

返回开放寻址的输出段,可以看到符合预期的结果:4.实现源代码(程序风格清晰易理解,有充分的注释)/** TridiagonalMatrix.h** Created on: Nov 22, 2015* Author: xudp*/#ifndef TRIDIAGONALMATRIX_H_#define TRIDIAGONALMATRIX_H_#include<iostream>using namespace std;template<class T>class TridiagonalMatrix {public:// 1、创建三对角矩阵类,采用按列映射方式,提供 store 和 retrieve 方法。

散列表设计

散列表设计
实验七 散列表设计
一、问题描述
针对某个集体中人名设计一个散列表,使得平均假设人名为中国人姓名的汉语拼音形式。待填入散列表的人名共有30个,取平均查找长度上限为2。
三、测试数据
取读者周围较熟悉的30人的姓名。
四、实现提示
(4)测试结果
可以用屏幕截屏。
如果随机函数自行构造,则应首先调整好随机函数,使其分布均匀。人名的长度不超过20个字符。可先对过长的人名作折叠处理。
五、实验报告主要内容
(1)题目要求
(2)设计
包括:记录结构的设计
散列函数和冲突处理方法的设计
软件结构的设计
(3)程序代码

散列表实验报告(不同装载因子下链表法和放寻址法对比)

散列表实验报告(不同装载因子下链表法和放寻址法对比)

散列表实验报告(不同装载因子下链表法和放寻址法对比)TOC \o “1-4“ \h \z \u 1 概述22 原理介绍22.1 散列表介绍22.2 直接寻址表32.3 散列函数32.3.1 除法散列42.3.2 乘法散列42.3.3 全域散列42.4 解决碰撞问题52.4.1 链接法52.4.2 开放寻址法52.4.2.1 线性探查62.4.2.2 二次探查62.4.2.3 双重散列73 算法说明73.1 概述73.2 使用链接法解决碰撞问题83.2.1 算法思想83.2.2 伪代码描述93.2.3 算法分析与证明103.3 使用开放寻址法的双重散列解决碰撞问题123.3.1 算法思想123.3.2 伪代码描述123.3.3 算法分析与证明143.4 两个算法的比较144 实验设计与分析165 C++实现与结果分析185.1 C++实现与结果185.2 结果分析266 实验总结和感想27概述该实验报告主要是通过介绍散列表的各种技术,包括散列函数、解决碰撞的机制等技术,并对两种解决碰撞的机制:链接法和开放寻址法进行分析和证明,并通过实验分析两者在不同的规模下的运行时间和空间占用的对比,来证明在“算法说明”一章中的理论分析。

原理介绍散列表介绍散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。

也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。

这个映射函数叫做散列函数,存放记录的数组叫做散列表。

它实际上是是普通数组概念的推广,因为可以对数组进行直接寻址,故可以而在O(1)时间内访问数组的任意元素。

如果存储空间允许,我们可以提供一个数组,为每个可能的关键字保留一个位置,就可以应用直接寻址技术。

基本概念若结构中存在关键字和K相等的记录,则必定在f(K)的存储位置上。

由此,不需比较便可直接取得所查记录。

称这个对应关系f为散列函数(Hash function),按这个思想建立的表为散列表。

数据结构实验C语言实现散列表

数据结构实验C语言实现散列表

实验课题:做这个实验时采用Open Addressing框架,也可加做Separate Chaining以形成比较。

1 构造散列表,把字符串数组中的各项加入到散列表中string MyBirds[13] = { "robin", "sparrow", "hawk", "eagle", "seagull", "bluejay", "owl", "cardinal", "Jakana", "Moa", "Egret", "Penguin", "hawk" };用C表示,可以是char * MyBirds[13] = { "robin", "sparrow", "hawk", "eagle", "seagull", "bluejay", "owl", "cardinal", "Jakana", "Moa", "Egret", "Penguin", "hawk" };为便于观察冲突现象,初始构造散列表时,表的容量不要过大,对Open Addressing,装载因子为0.5左右,对于Separate Chaining,装载因子为1左右即可。

也不要做rehash(应该改源代码的哪里,如何改)。

建议对源代码做些改动、增加一些输出(建议用条件编译控制这些输出),以便于观察冲突的发生和解决;对于Open Addressing,参考代码的冲突解决方案是用的平方探测(quadratic probing),如果用线性探测(linear probing)的策略,应该对函数findPos做什么修改(冲突解决的策略都集中在那里)#include<stdio.h>#include<stdlib.h>#include "hashquad.h"#include<string.h>#define MinTableSize 26typedef unsigned int Index;typedef Index Position;struct HashTbl;typedef struct HashTbl *HashTable;enum KindOfEntry { Legitimate, Empty, Deleted };struct HashEntry{char *Element;enum KindOfEntry Info;};typedef struct HashEntry Cell;struct HashTbl{int TableSize;Cell *TheCells;};static int NextPrime( int N ){int i;if( N % 2 == 0 )N++;for( ; ; N += 2 ){for( i = 3; i * i <= N; i += 2 )if( N % i == 0 )goto ContOuter;return N;ContOuter: ;}}Index Hash( const char *Key, int TableSize ){return *Key % TableSize;}HashTable InitializeTable( int TableSize ){HashTable H;int i;/* 1*/ if( TableSize < MinTableSize ){/* 2*/ printf( "Table size too small" );/* 3*/ return NULL;}/* Allocate table *//* 4*/ H = (struct HashTbl *)malloc( sizeof( struct HashTbl ) );/* 5*/ if( H == NULL )/* 6*/ printf( "Out of space" );/* 7*/ H->TableSize = NextPrime( TableSize );/* Allocate array of Cells *//* 8*/ H->TheCells = (struct HashEntry *)malloc( sizeof( Cell ) * H->TableSize );/* 9*/ if( H->TheCells == NULL )/*10*/ printf( "Out of space" );/*11*/ for( i = 0; i < H->TableSize; i++ ){H->TheCells[i].Element=(char *)malloc(10*sizeof(char));H->TheCells[i].Info=Empty;}/*12*//*13*/ return H;}Position Find( char *Key, HashTable H ){Position CurrentPos;int CollisionNum;/* 1*/ CollisionNum = 0;/* 2*/ CurrentPos = Hash( Key, H->TableSize );//printf("%d\n",CurrentPos);/* 3*/ while( H->TheCells[ CurrentPos ].Info != Empty &&strcmp(H->TheCells[ CurrentPos ].Element,Key)!=0 )/* Probably need strcmp!! */{if (H->TheCells[ CurrentPos ].Element!= NULL)printf("冲突: %s and %s\n", H->TheCells[ CurrentPos ].Element,Key);/* 4*/ CurrentPos += 2 * ++CollisionNum - 1;/* 5*/ if( CurrentPos >= H->TableSize )/* 6*/ CurrentPos -= H->TableSize;}/* 7*/ return CurrentPos;}void Insert( char *Key, HashTable H ){Position Pos;Pos = Find( Key, H );if( H->TheCells[ Pos ].Info != Legitimate ){/* OK to insert here */H->TheCells[ Pos ].Info = Legitimate;strcpy(H->TheCells[ Pos ].Element,Key);/* Probably need strcpy! */}}/*char*Retrieve( Position P, HashTable H ){return H->TheCells[ P ].Element;}*/void DestroyTable( HashTable H ){free( H->TheCells );free( H );}void main(){int i,x,n;char s[10];HashTable H;char * MyBirds[13] = { "robin", "sparrow", "hawk", "eagle", "seagull", "bluejay", "owl", "cardinal", "Jakana", "Moa", "Egret", "Penguin", "hawk" };printf(" \n");printf("原来的MyBirds:\n\n");printf(" 字符串位置\n");for(i=0;i<13;i++)printf("%8s: %2d\n",MyBirds[i],i+1);/*printf(" \n");printf("生成散列表:\n");n=Hash( Key, H->TableSize );for(i=0;i<13;i++)printf("%8s: %2d\n",MyBirds[i],i+1);*/H=InitializeTable( 29 );printf(" \n");printf("生成散列表:\n\n");printf(" 字符串散列值位置\n");for(i=0;i<13;i++)Insert(MyBirds[i] , H );for(i=0;i<29;i++){if(H->TheCells[i].Info!=Empty)printf("%8s: %2d %d\n",H->TheCells[i].Element,x=Hash(H->TheCells[i].Element,29),n=Find( H->TheCells[i].Element,H));}printf("请输入要查找的值:");scanf("%s",s);for(i=0;i<29;i++){if(strcmp(H->TheCells[i].Element,s)==0)break;}if(i<29)printf("查找成功,位置在:%d\n ",Find( s,H));else printf("查找失败\n");DestroyTable( H );}。

湖南大学数据结构试验8散列表问题

湖南大学数据结构试验8散列表问题

HUNAN UNIVERSITY 课程实习报告题目:散列表问题学生姓名刘乐学生学号20080820208专业班级通信工程2班指导老师朱宁波完成日期2010年6月8日一、需求分析:1.本程序来自于图书馆靠书名来检索想要查找的书问题。

2.本程序要求:(1)根据输入建立图书名称表,采用创建散列表实现。

(2)建散列表后,如果想要查找的数据在散列表中输出yes否则输出no。

3在dos系统下输入散列表内容和要查找的数据个数和数据。

4测试数据:二、概要设计为实现上述功能需要用到散列表的存储结构。

算法基本思想散列表存储的基本思想是用关键字的值决定数据元素的存储地址,散列表存储中解决碰撞的基本方法:①开放定址法:形成地址序列的公式是:Hi=(H(key)+di)% m,其中m是表长,di是增量。

根据di取法不同,又分为三种:a.di =1,2,…,m-1 称为线性探测再散列,其特点是逐个探测表空间,只要散列表中有空闲空间,就可解决碰撞,缺点是容易造成“聚集”,即不是同义词的关键字争夺同一散列地址。

b.di =12,-12,22,-22,… ,±k2(k≤m/2)称为二次探测再散列,它减少了聚集,但不容易探测到全部表空间,只有当表长为形如4j+3(j为整数)的素数时才有可能。

c.di =伪随机数序列,称为随机探测再散列。

②再散列法:Hi=RHi(key)i=1,2,…,k,是不同的散列函数,即在同义词产生碰撞时,用另一散列函数计算散列地址,直到解决碰撞。

该方法不易产生“聚集”,但增加了计算时间。

③链地址法:将关键字为同义词的记录存储在同一链表中,散列表地址区间用H[0..m-1]表示,分量初始值为空指针。

凡散列地址为i(0≤i≤m-1)的记录均插在以H[i]为头指针的链表中。

这种解决方法中数据元素个数不受表长限制,插入和删除操作方便,但增加了指针的空间开销。

这种散列表常称为开散列表,而①中的散列表称闭散列表,含义是元素个数受表长限制。

数据结构课程设计之散列表的设计与实现

数据结构课程设计之散列表的设计与实现

##大学数据结构课程设计报告题目:散列表的设计与实现院(系):计算机工程学院学生姓名:班级:学号:起迄日期: 2011.6.19-6.30指导教师:2010—2011年度第 2 学期一、需求分析1.问题描述:该题目要求设计散列表实现电话号码的查找,在建立散列表时分别要用姓名和电话号码作为关键字来建立,在建立时设计不同的散列函数以及利用不同的解决冲突的方法记录冲突的次数。

2.基本功能:本程序为实现对电话号码及其主要信息进行保存并查找,通过利用散列表实现查找功能。

实现了折叠法和除留余数法构造哈希函数,而在处理冲突时又分别用到了线性探测再散列和二次探测再散列。

3.输入输出:本程序需要输入的用户信息包含三个数据:姓名、电话号码、地址。

所用的数据类型是指针,而三个信息均为字符串(字符数组),并注意在输入姓名时需要输入拼音以便可以用折叠法构造哈希函数。

输出的用户信息是字符串。

二、概要设计1.设计思路:本程序用到了字符串,所以首先要定义各个字符串的长度;其次创建一个折叠函数,利用大写字母的八进制表示;分别用姓名和电话号码建立哈希表,由于电话号码是字符串,所以用atoi函数将字符串转换成整型。

2.数据结构设计:ADT HashTableSearch{数据对象D:D是具有相同特性的数据元素的集合。

数据关系R:数据元素同属一个集合。

基本操作P:CreatHash(HashTable h,Data a);初始条件:哈希函数存在操作结果:以a为关键字建立哈希表EQ(x,y);初始条件:哈希表已建立操作结果:验证两个关键字SearchHash(h,c);初始条件:哈希表已经建立操作结果:查找信息并输出冲突数}ADT HashTableSearch3.软件结构设计:Get函数void getmessage();打印函数void display();折叠函数int floding(char*);哈希函数int Hash(char*);冲突函数Status collision(int ,int);创建哈希表void CreatHash(HashTable*,Data*); 查找函数void SearchHash(HashTable*,int );三、详细设计#include<stdio.h>#include<string.h>#include<stdlib.h>#define SUCCESS 1#define UNSUCCESS 0#define DUPLICATE -1#define MAXSIZE 20 //数量#define MAX_SIZE 20//信息长度#define hashsize 51//hashtable长度最好为质数typedef int Status;typedef struct Data{char name[20];char tel[20];char add[20];};typedef struct{Data *elem[hashsize];int count;int sizeindex;}HashTable;int num;Data *a=0;HashTable h;Get函数void getmessage(){printf("需要输入用户的数量:");scanf("%d",&num);a=(Data*)malloc(num*sizeof(Data));for(int i=0;i<num;i++){printf("输入第%d用户的名字:",i+1);scanf("%s",a[i].name);printf("输入第%d用户的电话号码:",i+1);scanf("%s",a[i].tel);printf("输入第%d用户的地址:",i+1);scanf("%s",a[i].add);}}打印函数void display(){int i;for(i=0;i<num;i++)printf("名字%s 电话号码%s 地址%s\n",a[i].name,a[i].tel,a[i].add); }折叠函数int floding(char *s)// 用户名的折叠法{char str[20];char *a;int sum=0;strcpy(str,s);strupr(str);a=str;while(*a!=0){sum+=*a;*a++;}return sum;}哈希函数int Hash1(char *str)//折叠法哈希函数{int n;int m;n=floding(str);m=n%hashsize;return m;}int Hash2(char *str)//除留余数法哈希函数{int n;n=atoi(str);m=n%hashsize;return m;}解决冲突函数Status collision1(int &p,int &c)//线性探测再散列法解决冲突{int i,q;i=c/2+1;while(i<hashsize){if(c%2==0){c++;q=(p+i)%hashsize;if(q>=0)return q;elsei=c/2+1;}else{q=(p-i)%hashsize;c++;if(q>=0)return q;elsei=c/2+1;}}return UNSUCCESS;}Status collision2(int &p,int &c)//二次探测再散列法解决冲突{int i,q;i=c/2+1;while(i<hashsize){if(c%2==0){c++;q=(p+i*i)%hashsize;if(q>=0) return q;else i=c/2+1;else{q=(p-i*i)%hashsize;c++;if(q>=0) return q;else i=c/2+1;}}return UNSUCCESS;}构造哈希表函数void CreatHash1(HashTable *h,Data *a)//以姓名为关键字建立哈希表{int i,p,q,c;int n;printf("1.线性探测再散列\n");printf("2.二次探测再散列\n");printf("请选择解决冲突的方式:");scanf("%d",&n);for(i=0;i<num;i++){c=0;p=Hash1(a[i].name);q=p;while(h->elem[q]!=0){switch(n){case 1:q=collision1(p,c);break;case 2:q=collision2(p,c);break;}}h->elem[q]=&a[i];h->count++;printf("第%d个用户冲突的次数为%d次\n",i+1,c);}printf("以姓名方式建表成功\n");}void CreatHash2(HashTable *h,Data *a)//以电话号码为关键字建立哈希表{int i,p,q,c;int n;printf("1.线性探测再散列\n");printf("2.二次探测再散列\n");printf("请选择解决冲突的方式:");scanf("%d",&n);for(i=0;i<num;i++){c=0;p=Hash1(a[i].name);q=p;while(h->elem[q]!=0){switch(n){case 1:q=collision1(p,c);break;case 2:q=collision2(p,c);break;}}h->elem[q]=&a[i];h->count++;printf("第%d个用户冲突的次数为%d次\n",i+1,c);}printf("以电话号码方式建表成功\n");}Status EQ(char *x,char *y)//验证两个关键字是否一致{if(strcmp(x,y)==0)return 1;else return 0;}查找函数void SearchHash1(HashTable *h,int &c){ char str[20];int p,q;printf("请输入要查找的姓名:");scanf("%s",str);p=Hash1(str);q=p;while(h->elem[q]->name!=0&&!EQ(str,h->elem[q]->name))q=collision1(p,c);if(EQ(str,h->elem[q]->name)){printf("查找成功,用户信息为:\n");printf("姓名:%s 电话号码:%s 地址:%s \n",h->elem[q]->name,h->elem[q]->tel,h->elem[q]->add);}else printf("查找的用户不存在");}void SearchHash2(HashTable *h,int &c){ char str[20];int p,q;printf("请输入要查找的电话号码:");scanf("%s",str);p=Hash2(str);q=p;while(h->elem[q]->tel!=0&&!EQ(str,h->elem[q]->tel))q=collision2(p,c);if(EQ(str,h->elem[q]->tel)){printf("查找成功,用户信息为:\n");printf("姓名:%s 电话号码:%s 地址:%s \n",h->elem[q]->name,h->elem[q]->tel,h->elem[q]->add);}else printf("查找的用户不存在");}int main(){int m,c;while(1){printf(" ------------------------\n");printf(" 欢迎使用电话号码查找系统\n");printf(" ------------------------\n");printf(" 1.添加用户信息\n");printf(" 2.显示所有已添加用户的信息\n");printf(" 3.以姓名建立散列表\n");printf(" 4.以电话号码建立散列表\n");printf(" 5.输入姓名查找用户信息\n");printf(" 6.输入电话号码查找用户信息\n");printf(" 7.退出系统\n");printf(" **********************************************\n");printf(" *特别声明:输入名字时请输入拼音,不要输入汉字*\n");printf(" **********************************************\n");printf("请输入命令:");scanf("%d",&m);switch(m){case 1:getmessage();break;case 2:display();break;case 3:CreatHash1(&h,a);break;case 4:CreatHash2(&h,a);break;case 5:SearchHash1(&h,c);break;case 6:SearchHash2(&h,c);break;case 7: printf("谢谢您的使用\n");return 0;break;default :printf("输入数字不合法,请重新输入\n");break;}}return 0;}调用函数图如下:四、调试分析编写程序时,先是没有考虑到程序运行时需要字符串和整型数据之间的转换,修改中用到了atoi函数。

数据结构实验 散列表实验报告

数据结构实验 散列表实验报告

数据结构实验散列表实验报告一、实验目的本次实验的主要目的是深入理解和掌握散列表这种数据结构的基本原理、实现方法以及其在实际应用中的性能特点。

通过实际编写代码和进行相关测试,提高对散列表的操作能力,并能够分析和解决在使用散列表过程中可能遇到的问题。

二、实验原理散列表(Hash Table)是一种根据关键码值(Key value)而直接进行访问的数据结构。

通过一个特定的函数(哈希函数)将关键码映射到表中的一个位置来访问记录,以加快查找的速度。

这个映射函数称为哈希函数,存放记录的数组称为哈希表。

哈希函数的设计至关重要,它需要尽可能地将不同的关键码值均匀地分布在哈希表中,以减少冲突的发生。

常见的哈希函数有直接定址法、除留余数法、数字分析法等。

冲突解决方法也是散列表中的重要部分。

当不同的关键码通过哈希函数映射到相同的位置时,就会产生冲突。

常见的冲突解决方法有开放定址法(线性探测、二次探测等)和链地址法。

三、实验环境本次实验使用的编程语言为C++,开发工具为Visual Studio 2019。

四、实验内容1、哈希函数的实现采用除留余数法实现哈希函数。

代码如下:```cppint hashFunction(int key, int tableSize) {return key % tableSize;}```2、散列表的创建与初始化使用动态数组创建散列表,并将所有位置初始化为空。

```cppclass HashTable {private:int table;int size;public:HashTable(int tableSize) {size = tableSize;table = new intsize;for (int i = 0; i < size; i++){tablei =-1; //-1 表示为空}}~HashTable(){delete table;}};```3、数据插入操作采用线性探测法解决冲突。

散列法的实验研究 课程设计报告

散列法的实验研究  课程设计报告

课程设计报告问题描述:(1) 散列法中,散列函数构造方法多种多样,同时对于同一散列函数解决冲突的方法也可以不同。

两者是影响查询算法性能的关键因素。

(2) 程序实现几种典型的散列函数构造方法,并观察,不同的解决冲突方法对查询性能的影响。

a.需求分析:散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。

对不同的关键字可能得到同一散列地址,即key1≠key2,而f(key1)=f(key2),这种现象称冲突。

具有相同函数值的关键字对该散列函数来说称做同义词。

综上所述,根据散列函数H(key)和处理冲突的方法将一组关键字映象到一个有限的连续的地址集(区间)上,并以关键字在地址集中的“象”作为记录在表中的存储位置,这种表便称为散列表,这一映象过程称为散列造表或散列,所得的存储位置称散列地址。

散列表的查找过程基本上和造表过程相同。

一些关键码可通过散列函数转换的地址直接找到,另一些关键码在散列函数得到的地址上产生了冲突,需要按处理冲突的方法进行查找。

对散列表查找效率的量度,依然用平均查找长度来衡量。

查找过程中,关键码的比较次数,取决于产生冲突的多少,产生的冲突少,查找效率就高,产生的冲突多,查找效率就低。

因此,影响产生冲突多少的因素,也就是影响查找效率的因素。

该课程设计要求比较几种哈希函数的构造方法和解决冲突的方法对查询性能的影响。

b.概要设计该程序实现对哈希函数的构造方法、处理冲突的方法及在哈希表中查找数据的功能。

用线性再散列方法建立哈希表,用代码实现为:typedef structint key;int si;}HashTable1;void CreateHashTable1(HashTable1 *H,int *a,int num)//哈希表线性探测在散列;{int i,d,cnt;for(i=0;i<HashSize;i++){H[i].key=0;H[i].si=0;}for(i=0;i<num;i++){cnt=1;d=a[i]%HashSize;if(H[d].key==0){H[d].key=a[i];H[d].si=cnt;}else{do{d=(d+1)%HashSize;cnt++;}while(H[d].key!=0);H[d].key=a[i];H[d].si=cnt;}printf("\n线性再探索哈希表已建成!");}用二次探测再散列建立哈希表,代码实现如下:void CreateHash3(HashTable3 *h,int *a,int num)//二次探索表{int i,p=-1,c,pp;for(i=0;i<num;i++){c=0;p=a[i]%HashSize;pp=p;while(h->elem[pp]!=NULL){pp=Collision(p,c);if(pp<0){printf("第%d个记录无法解决冲突\n",i+1);continue;}}h->elem[pp]=&(a[a[i]]);h->count++;printf("第%d个记录冲突次数为%d\n",i+1,c);}printf("\n建表完成!\n此哈希表容量为%d,当前表内存储的记录个数%d.\n",HashSize,h->count);}二次探测再散列法解决冲突int Collision(int p,int &c){int i,q;i=c/2+1;while(i<HashSize){if(c%2==0){c++;q=(p+i*i)%HashSize;if(q>=0)return q;elsei=c/2+1;}else{q=(p-i*i)%HashSize;c++;if(q>=0)return q;else i=c/2+1;}}return (-1);}用线性再散列法查找,代码实现如下:void SearchHash1(HashTable1 *h,int data) {int d;d=data%HashSize;if(h[d].key==data)printf("数字%d的探查次数为:%d\n",h[d].key,h[d].si);else{dod=(d+1)%HashSize;while(h[d].key!=data && d<HashSize);if(d<HashSize)printf("数字%d的探查次数为:%d\n",h[d].key,h[d].si);elseprintf("没有查找到你所输入的数\n");}用二次探测再散列法查找void SearchHash2(HashTable2 * h[],int data,int num){int d;Node *q;d=data%num;q=h[d]->link;while(q->key!=data && q->next!=NULL)q=q->next;if(q->next!=NULL)printf("数字%d的查找次数为:%d\n",q->key,q->next);elseprintf("没有找到你要查找的那个数\n");}用链地址法查找,代码实现如下:void CreateHashTable2(HashTable2 *ht[],int *a,int num)//哈希表链地址;{int i,d,cnt;Node *s,*q;for(i=0;i<num; i++){ht[i]=(HashTable2 *)malloc(sizeof(HashTable2)); ht[i]->link=NULL;}for(i=0;i<num;i++){cnt=1;s=(Node *)malloc(sizeof(Node));s->key=a[i];s->next=NULL;d=a[i]%num;if(ht[d]->link==NULL){ht[d]->link=s;s->si=cnt;}else{q=ht[d]->link;while(q->next!=NULL){q=q->next;cnt++;}cnt++;s->si=cnt;q->next=s;}}}c.详细设计(1)程序中结构体的定义typedef struct{int key;int si;}HashTable1;typedef struct node{int key;int si;struct node *next;}Node;typedef struct{Node *link;}HashTable2;typedef struct{int * elem[HashSize];int count;int size;}HashTable3;(2) 主函数模块void main(){int data;HashTable1 hash1[HashSize];HashTable2 * hash2[HashSize];HashTable3 * ha;ha=(HashTable3 *)malloc(sizeof(HashTable3));for(int i=0;i<HashSize;i++)ha->elem[i]=NULL;ha->count=0;ha->size=HashSize;int a[MaxSize];while(1){printf("\n ┏━━━━━━━━━━━━━━━┓");printf("\n ┃欢迎使用本系统┃");printf("\n ┏〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓┓"); printf("\n ┃★★★★★★散列法的实验研究★★★★★★┃"); printf("\n ┃【1】. 添加数据信息【2】数据的输出┃"); printf("\n ┃【3】. 建立哈希表(线性再散列) ┃"); printf("\n ┃【4】. 建立哈希表(二次探测再散列) ┃"); printf("\n ┃【5】. 建立哈希表(链地址法) ┃"); printf("\n ┃【6】. 线性再散列法查找┃"); printf("\n ┃【7】. 二次探测再散列法查找┃"); printf("\n ┃【8】. 链地址法查找┃"); printf("\n ┃【0】. 退出程序┃"); printf("\n ┗〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓┛"); printf("\n");printf("\n");printf("请输入一个任务选项>>>");int x;scanf("%d",&x);switch(x){case 1:GetIn (a);break;case 2:GetOut(a);break;case 3:CreateHashTable1(hash1,a,num);break;case 4:CreateHash3(ha,a,num);break;case 5:CreateHashTable2(hash2,a,num);break;case 6:printf("请输入你查找的数据:");scanf("%d",&data);SearchHash1(hash1,data);break;case 7:printf("请输入你查找的数据:");scanf("%d",&data);SearchHash3(ha,data);break;case 8:printf("请输入你查找的数据:");scanf("%d",&data);SearchHash2(hash2,data,num);break;case 0:exit(-1);}}}d.调试分析(1)程序的关键是掌握文件的相关操作、哈希函数的创建和运用、处理冲突的方法等。

散列表实验报告

散列表实验报告

课程名称:数据结构实验项目:散列表题目:散列表实验一、需求分析1、实验目标掌握散列表的构造方法以及冲突处理方法,实现散列表的运算算法。

2、程序的输入和输出输入:void insertRec(char x[], char y[])输出:void print() {const char space[] = " ";int i, k;for (i = 0; i < N; i++) {k = H(a[i].key);cout << i << ":\t"<< a[i].key << "\t"<< a[i].value << "\t";if (strlen(a[i].key) > 0)cout << "(" << k << ")";cout << endl;}二、概要设计1、数据结构带头节点的线性链表。

主要的操作:查找节点,插入节点,更新节点,打印链表。

2、程序的模块分为两个程序文件。

主要模块如下:void init();void insertRec(char x[], char y[]);int searchRec(char x[]);int deleteRec(char x[]);void print();三、详细设计1、数据结构#include <cstdlib>#include <iostream>using namespace std;const int N = 17; //散列表长struct record { //记录char key[24];char value[24];int deleted;};record a[N]; //散列表int H(char key[]); //散列函数void init();void insertRec(char x[], char y[]);int searchRec(char x[]);int deleteRec(char x[]);void print();int main(int argc, char *argv[]){int i, k;char x[24], y[24];init();cout << "输入要插入的记录: \n";for (i = 0; i < 14; i++) {cin >> x >> y;insertRec(x, y);print();}system("PAUSE");return EXIT_SUCCESS;}void insertRec(char x[], char y[]) { int i, k;i = H(x);while (strlen(a[i].key) > 0) {i++; //线性探测if (i == N) i = 0; //绕回表头}strcpy(a[i].key, x);strcpy(a[i].value, y);}int deleteRec(char x[]) {}int searchRec(char x[]) {}int H(char key[]) {int i = key[0], j = key[1];return (i*i + j*j) % N;}void print() {const char space[] = " "; int i, k;for (i = 0; i < N; i++) {k = H(a[i].key);cout << i << ":\t"<< a[i].key << "\t"<< a[i].value << "\t";if (strlen(a[i].key) > 0)cout << "(" << k << ")"; cout << endl;}}void init() {int i;for (i = 0; i < N; i++) {strcpy(a[i].key, "");strcpy(a[i].value, "");a[i].deleted = 0;}}四、测试结果1、输入autumn 秋天2、输出0:1:2:3:4:5:6:7:8:9:10:11:12:autumn秋天<12>13:14:15:16:。

散列表的设计与实现报告

散列表的设计与实现报告

数据结构课程设计题目:散列表的设计与实现专业:计算机科学与技术指导教师:李竹林姓名:刘朋飞(1060309014004)何伟(1060309014042)输出记录开始进入录入系统获得关键字key用Hash1(key)计算地址比较nam_2(d)的值是否和关键字相等用探查序列d+i*hash2(key)计算(寻找)散列地址比较nam_Ht(d)的值是否和关键字相等未找到记录结束处理流程图3.功能模块设计:⑴.运用main函数输出电话本信息系统的整体界面,在调试运行后如下:⑵.利用添加功能 void getin(Record* a)实现用户信息的录入,在调试运行后如下:⑷.利用哈希函数CREA TEHASH1.2来构造哈希表并用Status collision函数的相应功能来查找并解决冲突:⑸.利用void SearchHash1(HashTable*H,int&c)在通讯录里查找姓名关键字,若查找成功,显示信息,c用来记录冲突次数,查找成功时显示冲突次数:三、详细设计与实现部分:定义头文件及基本属性#include<stdio.h>#include<iostream.h>#include<stdlib.h>#include<string>#include <windows.h>#define MAXSIZE20//电话薄记录数量#define MAX_SIZE 20 //人名的最大长度#define HASHSIZE 53 //定义表长#define SUCCESS 1#define UNSUCCESS -1#define LEN sizeof(HashTable)typedef int Status;typedef char NA[MAX_SIZE];定义结构体typedef struct{//记录NA name;NA tel;NA add;}Record;typedef struct{//哈希表Record *elem[HASHSIZE]; //数据元素存储基址int count; //当前数据元素个数int size; //当前容量}HashTable;关键字比较功能的实现Status eq(NA x,NA y){//关键字比较,相等返回 SUCCESS;否则返回 UNSUCCESSif(strcmp(x,y)==0)return SUCCESS;else return UNSUCCESS;}记录个数功能的实现Status NUM_BER; //记录的个数输入信息功能void getin(Record* a){//键盘输入各人的信息cout<<"输入要添加的个数:\n";cin>>NUM_BER;int i;for(i=0;i<NUM_BER;i++){cout<<"请输入第"<<i+1<<"个记录的用户名:\n";cin>>a[i].name;cout<<"请输入第"<<i+1<<"个记录的电话号码:\n";cin>>a[i].tel;cout<<"请输入第"<<i+1<<"个记录的地址:\n";cin>>a[i].add; //gets(str2);??????}}显示输入信息的实现void ShowInformation(Record* a)//显示输入的用户信息{int i;for( i=0;i<NUM_BER;i++)cout<<"\n 第"<<i+1<<"个用户信息:\n 姓名:"<<a[i].name<<"\n 电话号码:"<<a[i]. tel<<"\n联系地址:"<<a[i].add<<"\n";}清屏功能的实现void Cls(Record* a){cout<<"*";system("cls");}long fold(NA s){//人名的折叠处理char *p;long sum=0;NA ss;strcpy(ss,s);//复制字符串,不改变原字符串的大小写strupr(ss);//将字符串 ss 转换为大写形式p=ss;while(*p!='\0')sum+=*p++;cout<<"\nsum===================="<<sum;return sum;}构造哈希函数int Hash1(NA str){//哈希函数long n;int m;n=fold(str);//先将用户名进行折叠处理m=n%HASHSIZE; //折叠处理后的数,用除留余数法构造哈希函数return m; //并返回模值}int Hash2(NA str){//哈希函数long n;int m;n = atoi(str);//把字符串转换成整型数.m=n%HASHSIZE; //用除留余数法构造哈希函数return m; //并返回模值}冲突处理函数,用于解决冲突Status collision(int p,int &c){//冲突处理函数,采用二次探测再散列法解决冲突int i,q;i=c/2+1;while(i<HASHSIZE){if(c%2==0){c++;q=(p+i*i)%HASHSIZE;if(q>=0) return q;else i=c/2+1;}else{q=(p-i*i)%HASHSIZE;c++;if(q>=0) return q;else i=c/2+1;}}return UNSUCCESS;}void benGetTime();void CreateHash1(HashTable* H,Record* a){//建表,以人的姓名为关键字,建立相应的散列表benGetTime();int i,p=-1,c,pp;for(i=0;i<NUM_BER;i++){c=0;p=Hash1(a[i].name);pp=p;while(H->elem[pp]!=NULL) {pp=collision(p,c);if(pp<0){cout<<"第"<<i+1<<"记录无法解决冲突";//需要显示冲突次数时输出continue;}//无法解决冲突,跳入下一循环}H->elem[pp]=&(a[i]);//求得哈希地址,将信息存入H->count++;cout<<"第"<<i+1<<"个记录冲突次数为"<<c<<".\n";//需要显示冲突次数时输出}cout<<"\n 建表完成!\n 此哈希表容量为"<<HASHSIZE<<",当前表内存储的记录个数为"<<H- >count<<".\n";benGetTime();}查找功能的实现void SearchHash1(HashTable* H,int &c){//在通讯录里查找姓名关键字,若查找成功,显示信息benGetTime();NA str;cout<<"\n 请输入要查找记录的姓名:\n";cin>>str;int p,pp;p=Hash1(str);pp=p;while((H->elem[pp]!=NULL)&&(eq(str,H->elem[pp]->name)==-1))pp=collision(p,c);if(H->elem[pp]!=NULL&&eq(str,H->elem[pp]->name)==1){cout<<"\n 查找成功!\n 查找过程冲突次数为"<<c<<".以下是您需要要查找的信息:\n\n"; cout<<"姓名:"<<H->elem[pp]->name<<"\n 电话号码:"<<H->elem[pp]->tel<<"\n 联系地址:"<<H->elem[pp]->add<<"\n";}else cout<<"\n 此人不存在,查找不成功!\n";benGetTime();}void benGetTime(){SYSTEMTIME sys;GetLocalTime( &sys );out<<sys.wYear<<sys.wMonth<<sys.wDay<<sys.wHour<<sys.wMinute<<sys.wSecond<<sys.wMi lliseconds;}void CreateHash2(HashTable* H,Record* a){//建表,以电话号码为关键字,建立相应的散列表benGetTime();int i,p=-1,c,pp;for(i=0;i<NUM_BER;i++){c=0;p=Hash2(a[i].tel);pp=p;while(H->elem[pp]!=NULL) {pp=collision(p,c);if(pp<0){cout<<"第"<<i+1<<"记录无法解决冲突";//需要显示冲突次数时输出continue;}//无法解决冲突,跳入下一循环}H->elem[pp]=&(a[i]);//求得哈希地址,将信息存入H->count++;cout<<"第"<<i+1<<"个记录冲突次数为"<<c<<"。

《散列表的设计与实现》课程设计说明书

《散列表的设计与实现》课程设计说明书

届课程设计《散列表的设计与实现》设计说明书学生姓名学号所属学院信息工程学院专业计算机科学与技术班级计算机指导教师教师职称讲师塔里木大学教务处制目录前言 (1)1.1设计背景和意义 (1)1.1.1数据结构简介 (1)1.1.2选择算法的原因 (1)1.2设计的原理和内容 (1)正文 (1)2.1 设计的目的和意义 (1)2.2 目标和总体方案 (2)2.3 设计方法和内容 (2)2.3.1 硬件环境 (2)2.3.2软件环境 (2)2.3.3设计内容 (3)2.3.4 设计流程图 (3)2.4 设计创新与关键技术 (6)2.5结论 (6)2.5.1存在的问题 (6)2.5.2解决方案 (7)参考文献 (10)程序的设计思想和内容............................. 错误!未定义书签。

3.1程序设计的初始运行环境 .................... 错误!未定义书签。

3.2散列表的初始化............................ 错误!未定义书签。

3.3数据的插入................................ 错误!未定义书签。

3.4数据元素的查找............................ 错误!未定义书签。

3.5数据的删除................................ 错误!未定义书签。

3.6数据的合并................................ 错误!未定义书签。

3.7完成...................................... 错误!未定义书签。

前言1.1设计背景和意义1.1.1数据结构简介数据结构是计算机程序设计的重要理论设计基础,是一门综合性的专业基础科。

数据结构是研究数据之间的相互关系,也即数据的组织形式的一门科学。

它不仅是计算机学科的核心课程,数据结构是计算机存储、组织数据的方式。

数据结构实验报告(哈希表)

数据结构实验报告(哈希表)

散列表的设计实验报告1、题目:散列表的设计:针对某个集体中人名设计一个散列表,使得平均查找长度不超过R,并完成相应的建表和查表程序。

2、基本要求:假设人名为中国人姓名的汉语拼音形式。

待填入哈希表的人名共30个,取平均查找长度上限为2,哈希函数用除留余数法构造,用伪随机探测再散列法处理冲突。

人名长度不超过20个字符。

可先对过长的人名作折叠处理。

3、设计思想:a.构造哈希函数的方法很多,常用的有(1)直接定址法(2)数字分析法;(3)平方取中法;(4)折叠法;( 5)除留余数法;(6)随机数法;本实验采用的是除留余数法:取关键字被某个不大于哈希表表长m的数p除后所得余数为哈希地址H(key)=key MOD p,p<=m.b.哈希函数可以减少冲突,但不能避免。

通常用的处理冲突的方法有:(1)开放定址法,这种方法还包含三种形式,一种叫线性探测再散列,一种叫二次探测再散列,另一种叫伪随机探测再散列。

本实验采用的是第三种伪随机探测再散列。

求下一个开放地址的公式为:Hi=(H(k)+di)MOD m (Di=伪随机数序列)c.对哈希表的操作InitNameList() 操作结果:姓名(结构体数组)初始化CreateHashList() 操作结果:建立哈希表FindList() 操作结果:在哈希表中查找Display() 操作结果:显示哈希表4、程序结构图5、流程图6、数据测试7、程序清单#include<iostream>#include<string>using namespace std;#define HASH_LENGTH 50#define M 47#define NAME_NO 30typedef struct{ char *py;int k;}NAME;NAME NameList[HASH_LENGTH]; typedef struct{ char *py;int k;int si;//查找长度}HASH;HASH HashList[HASH_LENGTH]; void InitNameList(){ char *f;int r,s0,i;for (i=0; i<HASH_LENGTH; i++){NameList[i].py = new char[20];NameList[i].py[0] = 0;}strcpy(NameList[0].py, "lintingting"); strcpy(NameList[1].py, "chenxiaoping"); strcpy(NameList[2].py, "jianghaiyan"); strcpy(NameList[3].py, "wangtingting"); strcpy(NameList[4].py, "zhouhuihui"); strcpy(NameList[5].py, "zhuzhenguo"); strcpy(NameList[6].py, "wuqingwen"); strcpy(NameList[7].py, "chenzuopeng"); strcpy(NameList[8].py, "jinlining"); strcpy(NameList[9].py, "zhandakan"); strcpy(NameList[10].py, "linjiajia"); strcpy(NameList[11].py, "huangwenjun"); strcpy(NameList[12].py, "lizhongjing"); strcpy(NameList[13].py, "sushiding"); strcpy(NameList[14].py, "ouyangyaoyao"); strcpy(NameList[15].py, "chenwei");strcpy(NameList[16].py, "linxiaxiao"); strcpy(NameList[17].py, "zhanjie");strcpy(NameList[18].py, "baishujun"); strcpy(NameList[19].py, "gongqiaoqiao"); strcpy(NameList[20].py, "lvhaitao"); strcpy(NameList[21].py, "jiangqingsong"); strcpy(NameList[22].py, "gubaolong"); strcpy(NameList[23].py, "yehuaisong"); strcpy(NameList[24].py, "wangyuqin"); strcpy(NameList[25].py, "xuefeifei"); strcpy(NameList[26].py, "wujianshu"); strcpy(NameList[27].py, "zhanghuajiang"); strcpy(NameList[28].py, "zhengpan"); strcpy(NameList[29].py, "sudongdong");for(i=0;i<NAME_NO;i++){s0=0;f=NameList[i].py;for(r=0;*(f+r)!='\0';r++)s0=*(f+r)+s0;NameList[i].k=s0;}}void CreateHashList(){int i;for(i=0; i<HASH_LENGTH;i++){HashList[i].py=new char[20];HashList[i].py[0] = 0;HashList[i].k=0;HashList[i].si=0;}for(i=0;i<HASH_LENGTH;i++){int sum=0;int adr=(NameList[i].k)%M;int d=adr;if(HashList[adr].si==0) //如果不冲突{HashList[adr].k=NameList[i].k;HashList[adr].py=NameList[i].py;HashList[adr].si=1;}else //冲突{while (HashList[d].k!=0){d=(d+NameList[i].k%10+1)%M; //伪随机探测再散列法处理冲突sum=sum+1;};HashList[d].k=NameList[i].k;HashList[d].py=NameList[i].py;HashList[d].si=sum+1;}}}void FindList(){string name;int s0=0,r,sum=1,adr,d;cout<<"请输入人名的拼音:"<<endl;cin>>name;for(r=0;r<20;r++)s0+=name[r];adr=s0%M; //使用哈希函数d=adr;if(HashList[adr].k==s0)cout<<"姓名:"<<HashList[d].py<<endl<<"关键字:"<<s0<<endl<<"查找长度为: 1"<<endl;else if (HashList[adr].k==0)cout<<"无此记录!"<<endl;else{int g=0;while(g==0){d=(d+s0%10+1)%M;sum=sum+1;if(HashList[d].k==0){cout<<"无此记录!"<<endl;g=1;}if(HashList[d].k==s0){cout<<"姓名:"<<HashList[d].py<<endl<<"关键字:"<<s0<<endl<<"查找长度为:"<<sum<<endl;g=1;}};}}void Display(){int i;float average=0;cout<<"\n地址\t关键字\t\t搜索长度\tH(key)\t 姓名\n";for(i=0; i<50; i++){cout<<i<<" ";cout<<"\t"<<HashList[i].k<<" ";cout<<"\t\t"<<HashList[i].si<<" ";cout<<"\t\t"<<(HashList[i].k%M)<<" ";cout<<"\t "<<HashList[i].py<<" ";cout<<"\n";}for(i=0;i<HASH_LENGTH;i++)average+=HashList[i].si;average/=NAME_NO;cout<<"平均查找长度:ASL("<<NAME_NO<<")="<<average<<endl; }int main(){char x;InitNameList(); CreateHashList ();cout<<"d. 显示哈希表"<<endl<<"f. 查找"<<endl<<"任意键退出"<<endl<<"请选择:"<<endl;while(cin>>x){if(x=='d'){Display();cout<<endl;}else if(x=='f'){FindList();cout<<endl;}else break;}for (int i=0; i<HASH_LENGTH; i++){free(NameList[i].py);free(HashList[i].py);}return 0;}。

数据结构实验散列表

数据结构实验散列表

计算机科学与技术系之欧侯瑞魂创作哈希表的设计与实现项目陈说专业名称计算机科学与技术项目课程数据结构与算法项目名称哈希表的设计与实现班级项目人员钱海峰,郑秀娟,王传敏,杨青,凌波实验日期 2015.12.9目录一.设计目的 (3)二.问题分析 (3)三.设计环境 (3)四.人员分配 (3)五.详细设计和编码 (4)六.实验分析 (7)1测试分析 (7)2性能分析……………………………………………………11附录 (12)参考书目 (17)一.设计目的(1)掌握散列结构和散列函数的相关概念(2)掌握散列结构的存储结构的相关概念(2)掌握散列抵触的处置方法(3)运用散列解决抵触问题.二.问题分析要完成如下要求:设计哈希表实现整数查询系统.实现本项目需要解决以下问题:(1)如何设计一个哈希表.(2)如何在哈希表中拔出记录.(3)如何删除哈希表中的记录.(4)如何查找并显示记录.(5)如何解决抵触问题.三.设计环境⒈硬件:计算机每人一台.⒉软件:Windows把持系统和Microsoft Visual VC++6.0编译器.四.人员分配五.详细设计和编码1.界说结点结构类型在链地址法中,每个结点对应一个链表结点,由3个域组成,结构如图9-1所示.其中,key为关键字域,寄存结点关键字;data为数据域,寄存结点数据信息;next为链域,寄存指向下一个同义词结点的指针.图9-1 链地址法结点结构链地址数据结构类型如下:#define MAX_LENGTH 50typedef struct node{int data;struct node *next;}ElemNode;typedef struct{ElemNode *first;}ElemHeader,HashTable[MAX_LENGTH];#include <stdio.h>设计一个Hash()函数,本设计中对散列函数选择的是除留余数法,即对关键字进行模运算,将运算结果所得的余数作为关键字(或结点)的存储地址,即i=ht mod n,本设计n由用户自己输入,然后将计算出来的结果返回.具体设计如下:int Hash(int ht){ int i;i = ht%n;return i;}3.初始化散列链表初始化链地址散列算法只需要把散列表中所有表头结点的指针域置为NULL.初始化散列链表的算法如下:void initHashTable(HashTable ht,int n){int i;for(i =0;i<n;i++){ ht[i].first= NULL;}}在整个设计中,创立哈希表必需是第一步要做的,结点之前应先输入结点的个数,利用链地址法解决抵触.添加结点实际是调用了拔出结点函数insert(),需要利用哈希函数计算出地址,其次将结点拔出以关键字为地址的链表后.建立结点应包括静态申请内存空间,想地址中输入信息,同时最后一个结点中的next指针即是NULL.具体实现如下:int createHashTable(HashTable ht){HashTable *p=ht;int ad[MAX_LENGTH]={0};int i;printf("请输入拔出个数n:");scanf("%d",&n);printf("\n请输入拔出%d个整数:",n);for(i=0;i<n;i++)scanf("%d",&ad[i]);initHashTable(p,n);for(i=0;i<n;i++)insert(p,ad[i]);return 1;5.散列链表拔出结点算法将一个结点拔出到散列链表中,其算法分为以下几步:(1)根据结点关键字计算散列地址;(2)根据散列地址找到表头结点,并将结点拔出到对应的链表中.链地址法散列表的拔出算法如下:void insert(HashTable ht,int ele){int i;ElemNode *p;i=Hash(ele);p=(ElemNode *)malloc(sizeof(ElemNode));p->data = ele;p->next = ht[i].first;ht[i].first = p;}6.散列链表查找结点算法在散列链表中查找一个结点,其算法分为以下几步:(1)根据待查找关键字计算散列地址;(2)在散列地址所指向的单链表中顺序查找待查找关键字;(3)如果找到待查关键字,则返回指向该结点的指针;否则返回NULL.散列链表中查找结点的算法如下:ElemNode* search(HashTable ht,int ele){ int i;ElemNode *p;i = Hash(ele);p=ht[i].first;while(p!=NULL && p->data != ele){ p = p->next; }if(p!=NULL){printf("数据%d的位置为%d\n",ele,i);return p;}else{ printf("哈希表中无%d\n",ele);return p;}}7.散列链表删除结点算法在散列表中删除一个结点,其算法分为两步:(1)查找要删除的结点;(2)如果找到则删除,否则显示提示信息.在散列表中删除一个结点的算法如下:void dele(HashTable ht,int ele){//删除指定命据int i;ElemNode *p,*q;i = Hash(ele);p=ht[i].first;if(p == NULL){printf("error occurred! ");}if(p->data == ele){ht[i].first = p->next;}else {q= p->next;while(q!=NULL && q->data != ele){p=q;q = q->next;}if(q == NULL){printf("error occurred! ");}else{p->next = q->next;free(q);}}}六.实验分析1.测试分析(1)建立哈希表(2)拔出一个结点并显示:(3)查找结点:在哈希表中没有3这个数,会输出一行提示信息.(4)删除一个结点并显示:2.性能分析散列法实质上是一种通过关键字直接计算存储地址的方法.在理想情况下,散列函数可以把结点均匀地分布在散列表中,不发生抵触,则查找过程无需比力,其时间复杂度O(1).但在实际使用过程中,为了将范围广泛的关键字映射到一组连续的存储空间,往往会发生同义词抵触,这时就需要进行关键字比力.能够把关键字尽可能均匀地分布到散列表中的函数是“好”的散列函数.好的散列函数可以有效地降低抵触的的发生,从而提高查找性能.但好的散列函数和关键字的数字特征有关,因此不存在对任何结点都好的散列函数.对同一种散列函数,采纳分歧的抵触处置方法将发生分歧的效果,例如线性探测法容易招致“二次聚集”,而拉链法可以从根本上根绝二次聚集,从而提高查找性能.不外也会“浪费”一部份散列表的空间.附录****************************法式源代码*********************************//头文件#include <stdio.h>#include <stdlib.h>#define MAX_LENGTH 50typedef struct node{int data;struct node *next;}ElemNode;typedef struct{ElemNode *first;}ElemHeader,HashTable[MAX_LENGTH];int n;//存储哈希表长度void initHashTable(HashTable ht,int n);void insert(HashTable ht,int ele);ElemNode* search(HashTable ht,int ele);void dele(HashTable ht,int ele);int Hash(int ht);int createHashTable(HashTable ht);void showHashTable(HashTable ht);void menu(HashTable ht);//菜单//功能函数sanlibiao.c#include"sanlibiao.h"void initHashTable(HashTable ht,int n){//初始化int i;for(i =0;i<n;i++){ht[i].first= NULL;}}void insert(HashTable ht,int ele){//拔出int i;ElemNode *p;i=Hash(ele);p=(ElemNode *)malloc(sizeof(ElemNode)); // p->key = ele;p->data = ele;p->next = ht[i].first;ht[i].first = p;}ElemNode* search(HashTable ht,int ele){//查找int i;ElemNode *p;i = Hash(ele);p=ht[i].first;while(p!=NULL && p->data != ele){p = p->next;}if(p!=NULL){printf("数据%d的位置为%d\n",ele,i);return p;}else{printf("哈希表中无%d\n",ele);return p;}}void dele(HashTable ht,int ele){//删除指定命据int i;ElemNode *p,*q;i = Hash(ele);p=ht[i].first;if(p == NULL){printf("error occurred! ");}if(p->data == ele){ht[i].first = p->next;}else {q= p->next;while(q!=NULL && q->data != ele){p=q;q = q->next;}if(q == NULL){printf("error occurred! ");}else{p->next = q->next;free(q);}}}int Hash(int ht){//哈希函数int i;i = ht%n;return i;}int createHashTable(HashTable ht)//创立哈希表{HashTable *p=ht;int ad[MAX_LENGTH]={0};int i;printf("请输入拔出个数n:");scanf("%d",&n);printf("\n请输入拔出%d个整数:",n);for(i=0;i<n;i++)scanf("%d",&ad[i]);initHashTable(p,n);for(i=0;i<n;i++)insert(p,ad[i]);return 1;}void showHashTable(HashTable ht)//显示哈希表{int i;ElemNode *p;//i = Hash(ele);for(i=0;i<n;i++){p=ht[i].first;if(p!=NULL)printf("位置%d上的数据:",i);while(p!=NULL){printf("%d ",p->data);p = p->next;}if(ht[i].first!=NULL)printf("\n");}}void menu(HashTable ht){int p,h; //p 菜单选择;do{// system("cls");//清屏printf("★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆\n");printf("☆★☆★\n");printf("★☆************** 欢迎来到哈希表系统! ***************★☆\n");printf("☆★合肥学院☆★\n");printf("★☆计算机科学与技术★☆\n");printf("☆★钱海峰,郑秀娟,王传敏,杨青,凌波☆★\n");printf("☆★☆★\n");printf("☆★※※※※※※※☆★\n");printf("★☆※菜单※★☆\n");printf("☆★※※※※※※※☆★\n");printf("☆★☆★\n");printf("★☆************** (1)---创立哈希表******************★☆\n");printf("☆★************** (2)---查找******************★☆\n");printf("★☆************** (3)---删除******************★☆\n");printf("☆★************** (4)---拔出******************★☆\n");printf("★☆************** (5)---输出哈希表******************★☆\n");printf("☆★************** (0)---退出******************☆★\n");printf("★☆****************************************************★☆\n");printf("☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★☆★\n");printf("\n请在上述序号中选择一个并输入: ");scanf("%d",&p);switch(p){case 1:createHashTable(ht);break;case 2:printf("请输入要查找的数:\n");scanf("%d",&h);search(ht,h);break;case 3:printf("请输入要删除的数:\n");scanf("%d",&h);dele(ht,h);printf("\n");break;case 4:printf("请输入要拔出的数:\n");scanf("%d",&h);insert(ht,h);printf("\n");break;case5:showHashTable(ht);printf("\n");break;case 0: break; //退出default:printf("输入毛病!请重新输入!\n");break;}//system("pause");//系统暂停,提示按任意键继续....}while(p!=0); //for do}//主函数 mian.c#include "sanlibiao.h"int main(){HashTable ht;menu(ht);//进入菜单循环return 0;参考书目王昆仑,李红,《数据结构与算法》,中国铁道出书社,2007年6月初版.谭浩强,《C语言法式设计》,北京:清华年夜学出书社,2005年7月第三版.。

散列表的设计与实现-数据结构课程设计报告

散列表的设计与实现-数据结构课程设计报告
输入1实现查找记录功能,输入2实现姓名散列,输入3实现号码散列,输入4
实现清空记录,输入5实现保存记录,输入6实现退出系统。 Haxi()存储电话号码。
Haxi2()存储姓名。
input()输入节点。
addnode()添加节点。
create()新建节点。
create2()新建节点。
list()显示列表。
newname->next=nam[key2]->next;
nam[key2]->next=newname;
return 0;
}
void create()
{
int i;
phone=new phonenode[20];
for(i=0;i<20;i++)
{
phone[i]=new node;
phone[i]->next=NULL;
list2()显示列表。
find()查找用户信息。
find()查找用户信息。
save()保存用户信息。 c)详细设计:
#include "stdio.h"
#include "string.h"
#include "fstream.h" #include "iostream.h" #define NULL 0
p=p->next;
}
}
}
void find(char num[11]) {
haxi(num);
node *q=phone[key]->next;
while(q!= NULL)
{
if(strcmp(num,q->num)==0)

山东大学-数据结构实验报告-矩阵与散列表

山东大学-数据结构实验报告-矩阵与散列表

山东大学计算机科学与技术学院数据结构课程实验报告了Input函数和Output函数。

对问题三,仿课本所述,定义Term类作为SparseMatrix类的友元类,包含行、列、值三个要素的成员变量,用Term类的数组实现稀疏矩阵的行主映射存储。

查找行为的实现方式是,找到位于目标元素前一行的最后一个元素,再从这个元素开始向下搜索,直到找到和目标元素同一行但是列数小于目标元素的元素a[k-1],然后决定下一步的行为————插入一个新项Term作为a[k]并将已有元素向后移位,还是修改已存在的项a[k]。

以此原理编写了Store和Retrieve函数,并扩展编写了Input函数和Output函数。

对问题四,仿照课本例子编写了有序链表类SortedChain、开放寻址的散列表类HashTable、基于有序链表链接的散列表类ChainHashTable,并对这三个类分别扩展编写了Output函数。

3.测试结果(测试输入,测试输出)问题一:问题二:上图显示了输入不符合下三角方阵约束时,抛出异常并退出程序。

上图是正常运行的结果。

问题三:普通的输入和输出操作如下:矩阵相加:矩阵转置:问题四:以上图的数据为例。

从346就应该在链表链接的散列表上看到开放寻址解决冲突的例子。

返回开放寻址的输出段,可以看到符合预期的结果:4.实现源代码(程序风格清晰易理解,有充分的注释)/** TridiagonalMatrix.h** Created on: Nov 22, 2015* Author: xudp*/#ifndef TRIDIAGONALMATRIX_H_#define TRIDIAGONALMATRIX_H_#include<iostream>usingnamespace std。

template<class T>class TridiagonalMatrix {public:// 1、创建三对角矩阵类,采用按列映射方式,提供 store 和 retrieve 方法。

散列表实验报告doc

散列表实验报告doc

散列表实验报告doc散列表实验报告篇一:数据结构实验散列表实验报告课程实验报告课程名称:实验项目名称:专业班级:姓名:学号:完成时间:月背景散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。

也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。

这个映射函数叫做散列函数,存放记录的数组叫做散列表。

在理想情况下,查找、插入、删除操作的时间均为O(1),是一种高效的动态集合结构。

例1:计算机程序设计语言的编译程序需要维护一个符号表,其中元素的关键值为任意字符串,与语言中的标识符对应。

该符号表常采用散列表。

例2:为了节约空间,常常需要把文本文件采用压缩编码方式存储。

LZW是对文本文件进行压缩和解压缩的方法之一,该方法采用了散列。

问题描述我们希望在浩瀚的图书中,去发现一本书是否存在。

我们不知道书的编号,只知道它的书名。

(其实这已经不错了...)。

通过书名,来查询它是否存在。

为了简化问题,我们假设每本书的书名都是一组小写字母组成,长度不超过100字符。

基本要求(1)根据输入建立图书名称表,采用散列表实现该表,散列函数选用BKDE 字符串哈希。

(2)数据的输入输出格式:输入分为两部分第一部分,第一行是行数n,n 第二部分,第一行是行数m,m 输出:输出为m行,如果被查的记录存在,则输出"YES",如果不存在则输出"NO"。

测试数据输入:4aansandhellocppaban。

数据结构实验报告散列查找

数据结构实验报告散列查找

《数据结构》实验报告题目: 散列查找一、实验题目散列查找二、实验目的⑴掌握散列查找的基本思想;⑵掌握闭散列表的构造方法;⑶掌握线性探测处理冲突的方法;⑷验证散列技术的查找性能。

三、实验内容与实现⑴对于给定的一组整数和散列函数,采用线性探测法处理冲突构造散列表;⑵设计查找算法,验证查找性能。

实验实现:#include <stdio.h>#include <stdlib.h>#define HASHSIZE 10 // 长度#define NULLKEY -32768typedef struct{int *elem; // 数据元素存储地址,动态分配数组int count; // 当前数据元素个数}HashTable;int m = 0;int Init(HashTable *H){int i;m = HASHSIZE;H->elem = (int *)malloc(m * sizeof(int)); //分配内存H->count = m;for (i = 0; i<m; i++){H->elem[i] = NULLKEY;}return 1;}int Hash(int k)//除留余数法{return k % m;}void Insert(HashTable *H, int k)//插入数字如果有冲突用开放定址法{int addr = Hash(k);while (H->elem[addr] != NULLKEY){addr = (addr+1) % m;}H->elem[addr] = k;}int Search(HashTable *H, int k)//求哈希地址开放定址法解决冲突{int addr = Hash(k);while (H->elem[addr] != k){addr = (addr+1) % m;if (H->elem[addr] == NULLKEY || addr == Hash(k)) return -1;}return addr;}void Result(HashTable *H)//散列表元素显示{int i;for (i = 0; i<H->count; i++){if(H->elem[i]!=-32768)printf("%d ", H->elem[i]);}printf("\n");}int main(){int i, j, addr,n;HashTable H;int arr[HASHSIZE] = { NULL };Init(&H);printf("请输入数:");for (i = 0; i<10; i++)scanf("%d", &arr[i]);Insert(&H, arr[i]);}printf("输入的数存入哈希表后:");Result(&H);int b;printf("输入需要查找的数:\n");while(scanf("%d",&j)!=EOF){addr = Search(&H, j);if (addr == -1){printf("元素不存在,程序结束\n");break;}elseprintf("%d元素在表中的位置是:%d\n", j,addr+1); }}四、实验心得。

相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

散列表实验报告篇一:数据结构实验散列表实验报告课程实验报告课程名称:实验项目名称:专业班级:姓名:学号:完成时间:月背景散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。

也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。

这个映射函数叫做散列函数,存放记录的数组叫做散列表。

在理想情况下,查找、插入、删除操作的时间均为O(1),是一种高效的动态集合结构。

例1:计算机程序设计语言的编译程序需要维护一个符号表,其中元素的关键值为任意字符串,与语言中的标识符对应。

该符号表常采用散列表。

例2:为了节约空间,常常需要把文本文件采用压缩编码方式存储。

LZW是对文本文件进行压缩和解压缩的方法之一,该方法采用了散列。

问题描述我们希望在浩瀚的图书中,去发现一本书是否存在。

我们不知道书的编号,只知道它的书名。

(其实这已经不错了...)。

通过书名,来查询它是否存在。

为了简化问题,我们假设每本书的书名都是一组小写字母组成,长度不超过100字符。

基本要求(1)根据输入建立图书名称表,采用散列表实现该表,散列函数选用BKDE 字符串哈希。

(2)数据的输入输出格式:输入分为两部分第一部分,第一行是行数n,n 第二部分,第一行是行数m,m 输出:输出为m行,如果被查的记录存在,则输出"YES",如果不存在则输出"NO"。

测试数据输入:4aansandhellocppabanansandandehellocbbhellocpp输出:YESNONONOYESYESNONOYES实现提示(1)冲突处理方法为:顺次循环后移到下一个位置,寻找空位插入。

(2)BKDE 字符串哈希unsigned i(转载自:小草范文网:散列表实验报告)nt hash_BKDE(char *str)/* 初始种子 seed 可取31 131 1313 13131 131313 etc.. */while (*str) { hash = hash * seed + (*str++); unsigned int seed = 131; unsigned int hash = 0;} return (hash & 0x7FFFFFFF);将字符串哈希到小于2^31的整数 t,再将t用随机数哈希法映射到 2^15以内的数。

选做内容每一种西文图书都有一个国际标准图书编号,它是一个10位的十进制数字,若要以它作关键字建立一个哈希表,当馆藏书种类不到10,000时,采用折叠法构造一个四位数的哈希函数。

课后题目实现文本LZW压缩和解压缩。

源代码#include#include#includeusing namespace std;unsigned int hash_BKDE(char *str){unsigned int seed = 131;unsigned int hash = 0;while (*str){hash = hash * seed + (*str++);}return (hash & 0x7FFFFFFF);}double k=(double)(rand()%999)/1000; unsigned int hash_rand(unsigned int value) {double a=k*value;double n=(a-(int)a)*64;unsigned int seed=(int)n;return seed;}unsigned int Hash(char*str) {return hash_rand(hash_BKDE(str)); }class HashTable{public:HashTable();~HashTable();void insert(char*c);bool find(char*c);private:char**Arr;int ArrSize;};HashTable::HashTable(){ArrSize=32768;Arr=new char*[64];for(int i=0;i {Arr[i]=new char[100]; Arr[i]=NULL;}}HashTable::~HashTable(){for(int i=0;i delete[]Arr[i];delete []Arr;}void HashTable::insert(char*c) {unsigned int pos=Hash(c); while(Arr[pos]!=NULL)pos=(pos+1);Arr[pos]=c;}bool HashTable::find(char*c) {unsigned int pos=Hash(c); while(Arr[pos]!=NULL) {篇二:哈希表实验报告定稿数据结构课程设计报告设计题目:哈希表的设计与实现专业通信工程班级__________________ 学生__________________ 学号___________________ 指导教师起止时间 XXXXXX学院年学期目录一.设计要求------------------------------------------------------------------1二.数据结构选择与概要设计2.1 数据结构选择-------------------------------------------------------12.2 流程图--------------------------------------------------------------2以号码为关键字哈希流程----------------------------------2以姓名为关键字哈希流程----------------------------------3添加信息节点流程图----------------------------------------4姓名查找流程图----------------------------------------------5号码查询流程图----------------------------------------------6 三.设计算法3.1 建立节点------------------------------------------------------------73.2 哈希函数的定义---------------------------------------------------73.3 哈希查找------------------------------------------------------------8四.测试结果4.1 操作说明------------------------------------------------------------84.2 主菜单截图---------------------------------------------------------94.3 添加记录截图------------------------------------------------------94.4 散列结果截图-----------------------------------------------------104.5 查找记录截图-----------------------------------------------------104.5 清空记录截图-----------------------------------------------------11五.程序源代码及实验心得5.1 源代码----------------------------------------------------------11~205.2 实验心得-----------------------------------------------------------20一.设计要求【问题描述】设计哈希表实现电话号码查询系统。

设计程序完成以下要求:【基本要求】:(1)设每个记录有下列数据项:电话号码、用户名、地址;(2)从键盘输入各记录,分别以电话号码和用户名为关键字建立哈希表;(3)采用再哈希法解决冲突;(4)查找并显示给定电话号码的记录;(5)查找并显示给定用户的记录。

(6)在哈希函数确定的前提下,尝试各种不同类型冲突吃力方法(至少两种),考察平均查找长度思路:(1)对于以号码为关键字的散列函数,是将十一个数字全部相加,然后对20求余。

得到的数作为地址。

对于以用户名为关键字的散列函数,是将所有字母的ASCLL码值相加,然后对20求余。

(2)要添加用户信息,即要有实现添加结点的功能的函数,所以要设计一个必须包括一个输入结点信息、添加结点的函数;(3)要实现查找函数,则必须包括一个查找结点的函数;另外还有一个必不可少的就是运行之后要有一个主菜单,即要设计一个主函数(main())。

(4)测试数据的选择最后,程序完成后要对程序进行编译调试,执行后要选择数据进行测试,这里选择的测试数据为:1.姓名:郑治华;电话:;地址:湖北蕲春;2.姓名:蔡翔;电话:;地址:江苏宿迁;3.姓名:朱利庆;电话:;地址:湖北阳新;二.数据结构选择与概要设计2.1数据结构选择本设计涉及到的数据结构为:哈希表。

要求输入电话号码、用户名、地址三个信息,并要求分别以电话号码和用户名为关键字进行查找,所以本问题要用到两个哈希函数,进行哈希查找。

在链地址法中,每个结点对应一个链表结点,它由三个域组成,而由于该程序需要分别用电话号码和用户名为关键字建立哈希表,所以该链表结点它是由四个域组成,链接地址法结点结构如图:其中name[8]和num[11]是分别为以电话号码和用户名为关键字域,存放关键字(key);address[20](data)为结点的数据域,用来存储用户的地址。

Next指针是用来指向下一个结点的地址。

2.2流程图Hash函数流程图以号码为关键字的hash函数流程图以姓名为关键字的hash函数流程图。

相关文档
最新文档