散列表实验报告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语言实现散列表

实验课题:做这个实验时采用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散列表问题

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