哈希表的创建源程序

哈希表的创建源程序
哈希表的创建源程序

附件2

哈希表的创建源程序

#include

#include //time用到的头文件

#include //随机数用到的头文件

#include //toascii()用到的头文件

#include //查找姓名时比较用的头文件

#define HASH_LEN 50 //哈希表的长度

#define P 47 //小于哈希表长度的P

#define NAME_LEN 30 //姓名表的长度

typedef struct //姓名表

{

char *py; //名字的拼音

int m; //拼音所对应的ASCII码

}NAME;

NAME NameTable[HASH_LEN]; //全局定义姓名表

typedef struct //哈希表

{

char *py; //名字的拼音

int m; //拼音所对应的ASCII总和

int si; //查找长度

}HASH;

HASH HashTable[HASH_LEN]; //全局定义哈希表

int d[30],i,j; //全局定义随机数,循环用的i、j

//****************************************初始化函数******************************

void InitNameTable() //姓名表的初始化

{

NameTable[0].py="zhangyihao";

NameTable[1].py="qiujiaxing";

NameTable[2].py="zhoulei";

NameTable[3].py="xuweiying";

NameTable[4].py="zhanshengping";

NameTable[5].py="wangwenkai";

NameTable[6].py="gaodan";

NameTable[7].py="renkung";

NameTable[8].py="duixintong";

NameTable[9].py="mazhe";

NameTable[10].py="wangyongjie";

NameTable[11].py="kangwenhui";

NameTable[12].py="tianhuanhuan";

NameTable[13].py="zhouyuncheng";

NameTable[14].py="liangzhuang";

NameTable[15].py="zhangfan";

NameTable[16].py="wangpengfei";

NameTable[17].py="shafangfang";

NameTable[18].py="yanghuan";

NameTable[19].py="wangzhe";

NameTable[20].py="shirui";

NameTable[21].py="wangwenjuan";

NameTable[22].py="wangqian";

NameTable[23].py="chenyuhan";

NameTable[24].py="wangxin";

NameTable[25].py="guojing";

NameTable[26].py="tanqining";

NameTable[27].py="kangwenhui";

NameTable[28].py="songyangyang";

NameTable[29].py="yanfanglei";

for (i=0;i

{

int s=0;

char *p=NameTable[i].py;//定义字符指针接受哈希结构体的拼音值

for (j=0;*(p+j)!='\0';j++)

s+=toascii(*(p+j));//对p指针接受的拼音值进行转化,转化成相应的ASICC码数值

NameTable[i].m=s;

}

}

//****************************************创建函数******************************

void CreateHashTable() //建立哈希表

{

for(i=0;i

{

HashTable[i].py="\0";

HashTable[i].m =0;

HashTable[i].si=0;

}

for(i=0;i

int sum=1,j=0;

int adr=(NameTable[i].m)%P; //除留余数法H(key)=key MOD p,p<=m

if(HashTable[adr].si==0) //如果不冲突,将姓名表赋值给哈希表

{

HashTable[adr].m =NameTable[i].m;//填入码值

HashTable[adr].py=NameTable[i].py;//填入姓名拼音值

HashTable[adr].si=1; //不冲突的条件下,查找长度定义为1

}

else //如果冲突

{

while(HashTable[adr].si!=0)

{

adr=(adr+d[j++])%HASH_LEN; //伪随机探测再散列法处理冲突

sum=sum+1; //查找次数加1

}

HashTable[adr].m =NameTable[i].m; //将姓名表复制给哈希表对应的位置上

HashTable[adr].py=NameTable[i].py;

HashTable[adr].si=sum; //根据实际情况赋查找长度

}

}

}

//****************************************显示函数******************************

void DisplayNameTable() //显示姓名表

{

printf("\n地址\t\t 姓名\t\t 关键字\n");

for (i=0;i

printf("%2d %18s \t\t %d \n",i,NameTable[i].py,NameTable[i].m); //输出姓名值及ASCII码

}

void DisplayHashTable() // 显示哈希表

{

float ASL=0.0;//定义平均查找长度为浮点型

printf("\n\n 地址\t\t 姓名\t\t 关键字\t 搜索长度\n"); //显示的格式

for (i=0;i

{

printf("%2d %18s \t\t %d \t\t %d\n",i,HashTable[i].py,HashTable[i].m,HashTable[i].si);

ASL+=HashTable[i].si;

}

ASL/=NAME_LEN; //求得ASL

printf("\n\n平均查找长度:ASL(%d)=%f \n",NAME_LEN,ASL);

}

//****************************************查找函数******************************

void FindName() //查找

{

char name[20]={0};//初始化姓名数组

int s=0,sum=1,adr;

printf("\n请输入想要查找的姓名的拼音:");

scanf("%s",name);

for (j=0;j<20;j++) //求出姓名的拼音所对应的ASCII和作为关键字

s+=toascii(name[j]);

adr=s%P; //除留余数法

j=0;

if(HashTable[adr].m==s&&!strcmp(HashTable[adr].py,name)) //分3种情况进行判断,并输出超找结果

printf("\n姓名:%s 关键字:%d 查找长度为: 1\n",HashTable[adr].py,s);

else if (HashTable[adr].m==0)//

printf("没有想要查找的人!\n");

else

{

while(1)//处理冲突

{

adr=(adr+d[j++])%HASH_LEN; //伪随机探测再散列法处理冲突

sum=sum+1; //查找次数加1

if(HashTable[adr].m==0)

{

printf("没有想要查找的人!\n");

break;

}

if(HashTable[adr].m==s&&!strcmp(HashTable[adr].py,name))

{

printf("\n姓名:%s 关键字:%d 查找长度为:%d\n",HashTable[adr].py,s,sum);

break;

}

}

}

}

//****************************************主函数****************************** void main() //主函数

{

char a;

srand((int)time(0));

for(i=0;i<30;i++)//用随机函数求得伪随机数列d[i](在1到50之间)

d[i]=1+(int)(HASH_LEN*rand()/(RAND_MAX+1.0));

InitNameTable(); //调用初始化函数

CreateHashTable();//调用创建函数

printf(" 哈希表设计");//显示菜单栏

start:

printf("\n*----------------------------菜单栏------------------------------*\n");

printf(" \t\t\t 1. 显示姓名表\n");

printf(" \t\t\t 2. 显示哈希表\n");

printf(" \t\t\t 3. 查找\n");

printf(" \t\t\t 4. 退出\n");

printf("\n*----------------------------------------------------------------*\n");

restart:

printf("\n\t请选择:");

scanf("%s",&a);

switch(a) //多分枝选择结构对主菜单进行选择,根据选择进行判断,直到选择退出时才可以退出

{

case '1':

DisplayNameTable();

break;

case '2':

DisplayHashTable();

break;

case '3':

FindName();

break;

case '4':

exit(0);

break;

default:

printf("\n请输入正确的选择!\n");

goto restart;

}

goto start;

}

哈希表实现电话号码查询系统

哈希表实现电话号码查询系统 一目的 利用《数据结构》课程的相关知识完成一个具有一定难度的综合设计题目,利用 C/C++语言进行程序设计,并规范地完成课程设计报告。通过课程设计,巩固和加深对线性表、栈、队列、字符串、树、图、查找、排序等理论知识的理解;掌握现实复杂问题的分析建模和解决方法(包括问题描述、系统分析、设计建模、代码实现、结果分析等);提高利用计算机分析解决综合性实际问题的基本能力。 二需求分析 1、程序的功能 1)读取数据 ①读取原电话本存储的电话信息。 ②读取系统随机新建电话本存储的电话信息。 2)查找信息 ①根据电话号码查询用户信息。 ②根据姓名查询用户信息。 3)存储信息 查询无记录的结果存入记录文档。 2、输出形式 1)数据文件“old.txt”存放原始电话号码数据。 2)数据文件“new.txt”存放有系统随机生成的电话号码文件。 3)数据文件“out.txt”存放未查找到的电话信息。 4)查找到相关信息时显示姓名、地址、电话号码。 3、初步测试计划 1)从数据文件“old.txt”中读入各项记录,或由系统随机产生各记录,并且把记录保存 到“new.txt”中。 2)分别采用伪随机探测再散列法和再哈希法解决冲突。 3)根据姓名查找时显示给定姓名用户的记录。 4)根据电话号码查找时显示给定电话号码的用户记录。

5)将没有查找的结果保存到结果文件Out.txt中。 6)系统以菜单界面工作,运行界面友好,演示程序以用户和计算机的对话方式进行。三概要设计 1、子函数功能 int Collision_Random(int key,int i) //伪随机数探量观测再散列法处理冲突 void Init_HashTable_by_name(string name,string phone,string address) //以姓名为关键字建立哈希表 int Collision_Rehash(int key,string str) //再哈希法处理冲突 void Init_HashTable_by_phone(string name,string phone,string address) //以电话号码为关键字建立哈希表 void Outfile(string name,int key) //在没有找到时输出未找到的记录,打开文件out.txt并将记录储存在文档中void Outhash(int key) //输出哈希表中的记录 void Rafile() //随机生成数据,并将数据保存在new.txt void Init_HashTable(char*fname,int n) //建立哈希表 int Search_by_name(string name) //根据姓名查找哈希表中的记录 int Search_by_phone(string phone) //根据电话号码查找哈希表中的记录

汉诺塔栈c语言

计算机科学与工程学院 《算法与数据结构》试验报告[二] 专业班级10级计算机工程02 试验地点计算机大楼计工教研室学生学号1005080222 指导教师蔡琼 学生姓名肖宇博试验时间2012-4-14 试验项目算法与数据结构 试验类别基础性()设计性()综合性(√)其它() 试验目的及要求(1)掌握栈的特点及其存储方法;(2)掌握栈的常见算法以及程序实现;(3)了解递归的工作过程。 成 绩评定表 类别评分标准分值得分合计 上机表现积极出勤、遵守纪律 主动完成设计任务 30分 程序与报告程序代码规范、功能正确 报告详实完整、体现收获 70分 备注: 评阅教师: 日期:年月日

试 验 内 容 一、实验目的和要求 1、实验目的: (1)掌握栈的特点及其存储方法; (2)掌握栈的常见算法以及程序实现; (3)了解递归的工作过程。 2、实验内容 Hanoi 塔问题。(要求4个盘子移动,输出中间结果) 3、实验要求: 要求实现4个盘子的移动,用递归和栈实现。 二、设计分析 三个盘子Hanoi 求解示意图如下: 三个盘子汉诺塔算法的运行轨迹: B A B C A B C A C A B C (a (b) (c (d) ⑸ ⑼ ⑶ Hanio(3,A,B,C) Hanio(3,A,B,C) Hanio(2,A,C,B) Hanio(2,A,C,B) Hanio(1,A,B,C) Hanio(1,A,B,C) Move (A,C) Move (A,B) Hanio(1,C,A,B) Hanio(1,C,A,B) Move (C,B) Move (A,B) Hanio(2,B,A,C) Hanio(2,B,A,C) Hanio(1,B,C,A) Hanio(1,B,C,A) Move (B,C) Hanio(1,A,B,C) Hanio(1,A,B,C) Move (A,C) Move (B,A) 递归第一层 递归第二层 递归第三层 ⑴ ⑵ ⑷ ⑹ ⑺ ⑻ ⑽ ⑾ ⑿ ⒀ ⒁

ii.c语言本质26链表、二叉树和哈希表3哈希表

第 26 章链表、二叉树和哈希表 3. 哈希表 下图示意了哈希表(Hash Table)这种数据结构。 图 26.12. 哈希表 如上图所示,首先分配一个指针数组,数组的每个元素是一个链表的头指针,每个链表称为一个槽(Slot)。哪个数据应该放入哪个槽中由哈希函数决定,在这个例子中我们简单地选取哈希函数h(x) = x % 11,这样任意数据x都可以映射成0~10之间的一个数,就是槽的编号,将数据放入某个槽的操作就是链表的插入操作。 如果每个槽里至多只有一个数据,可以想像这种情况下search、insert和delete 操作的时间复杂度都是O(1),但有时会有多个数据被哈希函数映射到同一个槽中,这称为碰撞(Collision),设计一个好的哈希函数可以把数据比较均匀地分布到各个槽中,尽量避免碰撞。如果能把n个数据比较均匀地分布到m个槽中,每个糟里约有n/m个数据,则search、insert和delete和操作的时间复杂度都是O(n/m),如果n和m的比是常数,则时间复杂度仍然是O(1)。一般来说,要处理的数据越多,构造哈希表时分配的槽也应该越多,所以n和m成正比这个假设是成立的。

请读者自己编写程序构造这样一个哈希表,并实现search、insert和delete 操作。 如果用我们学过的各种数据结构来表示n个数据的集合,下表是search、insert 和delete操作在平均情况下的时间复杂度比较。 表 26.1. 各种数据结构的search、insert和delete操作在平均情况下的时间复杂度比较 数据结构search insert delete O(n),有序数组折半查找是O(lgn)O(n)O(n) 数组 双向链表O(n)O(1)O(1) 排序二叉树O(lgn)O(lgn)O(lgn) 哈希表(n与槽数m成正比)O(1)O(1)O(1) 习题 1、统计一个文本文件中每个单词的出现次数,然后按出现次数排序并打印输出。单词由连续的英文字母组成,不区分大小写。 2、实现一个函数求两个数组的交集:size_t intersect(const int a[], size_t nmema, const int b[], size_t nmemb, int c[], size_t nmemc);。数组元素是32位int型的。数组a有nmema个元素且各不相同,数组b有nmemb个元素且各不相同。要求找出数组a和数组b的交集保存到数组c中,nmemc是数组c 的最大长度,返回值表示交集中实际有多少个元素,如果交集中实际的元素数量超过了nmemc则返回nmemc个元素。数组a和数组b的元素数量可能会很大(比如上百万个),需要设计尽可能快的算法。

哈希表查找的设计

哈希表查找的设计 一.问题描述: 哈希表查找的设计:设哈希表长为20,用除留余数法构造一个哈希函数,以开放定址法中的线性探测再散列法作为解决冲突的方法,编程实现哈希表查找、插入和建立算法。二.需求分析: 程序可实现用户与计算机的交互过程。在计算机显示提示信息后,可由用户键入运算命令以实现对应的功能,包含数据的录入、查找、删除、显示等功能。 本程序旨在实现哈希函数的构造与处理存储冲突,因而指定哈希表存储的数据类型为简单的整型数字,在实用性上还有所欠缺。但根据用户需求的变化,可以对程序的基本数据类型进行改造,以实现更为丰富的功能,进而体现哈希表在查找数据时的优越性。 三.算法思想: 在设定哈希表的抽象数据类型时,要有查找数据元素的操作。另外,插入操作和删除操作也要用到查找数据元素操作,以查看该数据元素是否存在,因此可以设计查找元素操作包括插入和删除操作的查找。 因此,查找操作就有两种情况:一种情况是插入操作时寻找空闲单元的查找;另一种情况是在查找和删除操作时寻找该元素是否在哈希表中已存在的查找。插入操作时寻找空闲单元查找的特征是哈希表中不存在该对象,设计此时查找函数返回该空闲单元位置的“正”值;查找和删除操作时寻找该元素是否在哈希表中已存在的特征是哈希表中已存在该数据元素,设计此时查找函数返回该数据单元位置的“负”值。进而执行后续操作。 为了区分哈希表中每一个表元素的当前状态,为每一个表元素设置一个“标志”定为tag。tag=0表示该元素为空;tag=1表示该元素以存放有数据元素;tag=-1表示该元素中存放的数据元素已被删除。判断当tag为0或-1时都可以进行插入操作。

哈希表设计-数据结构课程设计

实习6、哈希表设计 一、需求分析 1. 问题描述 针对某个集体(比如你所在的班级)中的“人名”设计一个哈希表,使得平均查找长度均不超过R,完成相应的建表和查表顺序。 2. 基本要求 假设人名为中国人姓名的汉语拼音形式。待填入哈希表的人名共有30个,取平均查找长度的上限为2。哈希函数用除留余数法构造,用伪随机探测再散列法处理冲突。 3. 测试数据 取读者周围较熟悉的30个人的姓名。 4. 实现提示 如果随机数自行构造,则应首先调整好随机函数,使其分布均匀。人名的长度均不超过19个字符(最长的人名如:庄双双(Zhuang Shuangshuang))。字符的取码方法可直接利用C 语言中的toascii函数,并可先对过长的人名先作折叠处理。 二、概要设计 ADT Hash { 数据对象D:D是具有相同特征的数据元素的集合。各数据元素均含有类型相同,可唯一标识数据元素的关键字。 数据关系R:数据元素同属一个集合。 InitNameTable() 操作结果:初始化姓名表。 CreateHashTable() 操作结果:建立哈希表。 DisplayNameTable() 操作结果:显示姓名表。 DisplayHashTable() 操作结果:显示哈希表。 FindName() 操作结果:查找姓名。 }ADT Hash 三、详细设计(源代码) (使用C语言) #include #include//time用到的头文件 #include//随机数用到的头文件 #include//toascii()用到的头文件 #include//查找姓名时比较用的头文件 #define HASH_LEN 50//哈希表的长度 #define P 47//小于哈希表长度的P #define NAME_LEN 30//姓名表的长度 typedef struct {//姓名表 char *py; //名字的拼音 int m; //拼音所对应的 }NAME; NAME NameTable[HASH_LEN]; //全局定义姓名表 typedef struct {//哈希表 char *py; //名字的拼音

哈希表查询设计及实现

/* (1)设计哈希表,该表应能够容纳50个英文单词。 (2)对该哈希表进行查询,实现对特定单词的快速查询,并显示经过的节点内容 已经发到你邮箱里了enochwills@https://www.360docs.net/doc/ff5378751.html, */ #include #include #include #include #include #define szNAME 80 #define HASH_ROOT 47 /*用于计算哈希地址的随机数*/ #define szHASH 50 /*哈希表总长度*/ #define POPULATION 30 /*学生总数*/ /*哈希表结构体*/ struct THash { int key; /*钥匙码*/ char name[10]; /*姓名*/ int depth; /*检索深度*/ }; /*根据钥匙码和哈希根计算哈希地址*/ int GetHashAddress(int key, int root) { return key % root; }/*end GetHashAddress*/ /*冲突地址计算,如果发现地址冲突,则用当前地址和钥匙码、哈希根重新生成一个新地址*/ int GetConflictAddress(int key, int address, int root) { int addr = address + key % 5 + 1; return addr % root; }/*end GetConflictAddress*/ /*根据字符串生成哈希钥匙码,这里的方法是将串内所有字符以数值形式求累加和*/ int CreateKey(char * name) { int key = 0; unsigned char * n = (unsigned char *)name; while(*n) key += *n++; return key; }/*end CreateKey*/ /*输入一个名字,并返回哈希钥匙码*/ int GetName(char * name) { scanf("%s", name); return CreateKey(name); }/*end CreateKey*/ /*根据学生人数、长度和哈希根构造哈希表*/ struct THash * CreateNames(int size, int root, int population) { int i =0, key = 0, addr = 0, depth = 0; char name[10]; struct THash * h = 0, *hash = 0; /*哈希根和长度不能太小*/ if(size < root || root < 2) return 0; /*根据哈希表长度构造一个空的哈希表*/ hash = (struct THash *)malloc(sizeof(struct THash) * size); /*将整个表清空*/ memset(hash, 0, sizeof(struct THash) * size); for(i = 0; i < population; i++) { /*首先产生一个随机的学生姓名,并根据姓名计算哈希钥匙码,再根据钥匙码计算地址*/ key = GetName(name); addr = GetHashAddress(key, root); h = hash + addr; if (h->depth == 0) { /*如果当前哈希地址没有被占用,则存入数据*/ h->key = key; strcpy(h->name , name); h->depth ++; continue; }/*end if*/ /*如果哈希地址已经被占用了,就是说有冲突,则寻找一个新地址,直到没有被占用*/ depth = 0; while(h->depth ) { addr = GetConflictAddress(key, addr, root); h = hash + addr; depth ++; }/*end while*/ /*按照新地址存放数据,同时记录检索深度*/ h->key = key; strcpy(h->name , name); h->depth = depth + 1; }/*next*/ return hash; }/*end CreateNames*/ /*在哈希表中以特定哈希根查找一个学生的记录*/ struct THash * Lookup(struct THash * hash, char * name, int root) { int key = 0, addr = 0; struct THash * h = 0; /*不接受空表和空名称*/ if(!name || !hash) return 0; key = CreateKey(name); addr = GetHashAddress(key, root); h = hash + addr; /*如果结果不正确表示按照冲突规则继续寻找*/ while(strcmp(h->name , name)) { addr = GetConflictAddress(key, addr, root); h = hash + addr; if(h->key == 0) return 0; }/*end while*/ return hash + addr; }/*end Lookup*/ /*根据一条哈希表记录打印该记录的学生信息*/ void Print(struct THash * record) { if (!record) { printf("【查无此人】\n"); return ; }/*end if*/ if(record->depth) printf("【钥匙码】%04d\t【姓名】%s\t【检索深度】%d\n", record->key, record->name, record->depth ); else printf("【空记录】\n"); /*end if*/ }/*end Print*/ /*打印学生花名册*/ void Display(struct THash * hash, int size) { struct THash * h = 0; if (!hash || size < 1) return ; printf("学生花名册:\n"); printf("--------------------\n"); for(h = hash; h < hash + size; h++) { printf("【地址】%d\t", h - hash); Print(h); }/*next*/ printf("--------------------\n"); }/*end Display*/ /*主函数,程序入口*/ int main(void) { /*哈希表变量声明*/ struct THash * hash = 0, * h = 0; int cmd = 0; /*命令*/ char name[10]; /*学生姓名*/ /*生成30个学生用的哈希表*/ hash =

856数据结构(C语言版)试卷

姓名: 报考专业: 准考证号码: 密封线内不要写题 年全国硕士研究生招生考试初试自命题试题科目名称:数据结构(C 语言版) 科目代码:考试时间:3小时 满分 150 分 可使用的常用工具:√无 □计算器 □直尺 □圆规(请在使用工具前打√)所有答题内容必须写在答题纸上,写在试题或草稿纸上的一律无效;考完后试题随答题纸交回。 小题,每小题2分,共20分) (最多元素为MaxSize )为空时,其栈顶指针top 栈满的条件是( )。 ST.top != -1 B )ST.top == -1 ST.top != MaxSize – 1 D )ST.top == MaxSize –是结点 p 的直接前趋,若在 q 与 p 之间插入结点

9. 在Hash函数H(k)=k MOD m中,一般来讲m应取()。 A)奇数 B)偶数 C)素数 D)充分大的数 10.用二分插入排序法进行排序,被排序的表应采用的数据结构是()。 A)数组 B)单链表 C)双向链表 D)散列表 二、填空题(共10小题,每小题2分,共20分) 1. 一个栈的入栈序列为1,2,3,…,n,其出栈序列是p1,p2,p3,…,pn。若p2 = 3, 则p3可能取值的个数是()。 2. 已知单链表A长度为m,单链表B长度为n,若将B连接在A的末尾,在没有链 尾指针的情形下,算法的时间复杂度应为()。 3. 从一个具有n个结点的有序单链表中查找其值等于x的结点时,在查找成功的 情况下,需要平均比较()个结点。 4. 对于一个有N个结点、K条边的森林,共有()棵树。 5. 若以{4,5,6,3,8}作为叶子节点的权值构造哈夫曼树,则带权路径长度是 ()。 6. 有向图包含5个顶点(编号从1到5)6条弧(<1,2>,<1,5>,<1,3>,<2,3>, <3,4><5,4>)。该图进行拓扑排序,可以得到()个拓扑序列。 7. 对于一个有向图,若一个顶点的入度为k1,出度为k2,则对应邻接表中该顶点 邻接点单链表中的结点数为()。 8. 设哈希函数H(K)=3 K mod 11,哈希地址空间为0~10,对关键字序列(32, 13,49,24,38,21,4,12)按线性探测法解决冲突的方法构造哈希表,则该哈希表等概率下查找成功的平均查找长度为()。 9. 对于长度为n的线性表,若进行顺序查找,则时间复杂度为()。 10. 排序方法中,从未排序序列中依次取出元素与已排序序列(初始为空)中的元 素进行比较,将其放入已排序序列的正确位置上的方法称为()。 三、判断题(对的答√错的答×,共10小题,每小题2分,共20分) 1. 不论是入队列还是入栈,在顺序存储结构上都需要考虑“溢出”情况。 2. 在顺序表中取出第i个元素所花费的时间与i成正比。 3. 线性表的插入、删除总是伴随着大量数据的移动。 4. 二叉树通常有顺序存储结构和链式存储结构。 5. 对N(≥2)个权值均不相同的字符构造哈夫曼树,则树中任一非叶结点的权值一 定不小于下一层任一结点的权值。 6. Prim 算法通过每步添加一条边及相连顶点到一棵树,从而生成最小生成树。 7. 用邻接矩阵存储图,占用的存储空间只与图中结点数有关,而与边数无关。 8. 散列查找主要解决的问题是找一个好的散列函数和有效解决冲突的办法。 9. 对长度为10的排好序的表用二分法检索,若检索不成功,至少需比较10次。 10. 对5个不同的数排序至少需要比较4次。 四、综合应用题(第1小题15分,第2,3,4小题各10分,共45分) 1. 分别给出在先序线索二叉树、中序线索二叉树和后序线索二叉树中结点p的直 接后继结点所在位置。 线索二叉树中结点的结构包括数据域data、左孩子域left、右孩子域right、

该程序实现的哈希表构造哈希函数的方法为除留余数法(

一、该程序实现的哈希表:构造哈希函数的方法为除留余数法(函数modhash),处理哈希冲突的方法为链地址法。 二、对哈希表的操作:插入(函数hash_table_insert)、移除(函数hash_table_remove)、 查找(函数hash_table_lookup)、整个哈希表的释放(函数hash_table_delete)、 整个哈希表的输出(函数hash_table_print)。 三、哈希表的最大长度可以由HASHMAXLEN设置(我设为1000)。 四、输入哈希表的名称拼音字符是长度为10—20(长度可由STR_MAX_LEN和STR_MIN_LEN)的小写字母组成。这些名字字符串是我用函数rand_str随机产生的。 五、名称拼音字符(关键字)到关键字值的转换方法:先把名称的拼音字符转换对应的ASCII,累加后作为关键字值。我是用函数str_to_key实现的。 六、异常情况包括: 1、在对哈希表进行插入操作时,若哈希表的实际长度超过了哈希表的最大长度,我就输出“out of hash table memory!”,然后直接跳出插入子函数,不进行插入操作。 2、在对哈希表进行插入操作时,若插入的元素在哈希表中已经存在,我就输出“******already exists !”,然后直接跳出插入子函数,不进行插入操作。 3、在对哈希表进行查找操作时,若查到则返回其地址,若没查到则返回空地址。 4、在对哈希表进行移除操作时,对同义词元素的删除,分为表头和表中两种情况处理。 七、开发平台:DEV-C++,用c语言实现。 在哈希表程序中我比较注重整个代码风格,希望能形成很好的代码风格!如果有什么可以改进的,希望老师能跟我说说!

哈希表的查找 2

华北电力大学 实验报告 实验名称哈希表的设计 课程名称算法与数据结构实验 专业班级:学生姓名: 学号:成绩: 指导教师: 实验日期:

一、实验目的及要求 1.内容描述 设计哈希表实现电话号码查询系统: 1)设每个记录有如下数据项:电话号码、用户名、地址; 2)从键盘输入各个记录,以电话号码为关键字建立哈希表(至少要有12个以上的记录,哈希表的哈希表的长度为8); 3)用链地址法解决冲突; 4)显示建立好的哈希表,并且对其进行查找,删除和插入给定关键字值得记录。 二、所用仪器、设备 VC++ 6.0环境 三、实验说明 1.采用除留余数法进行哈希表的散列,即以电话号码作为主关键字,将电话号码的11位相加,按照模7取余; 2.解决冲突用链地址法。 3.将用户信息包装在结构体节点中 struct node //建节点 { char name[8],address[20]; char num[11]; node * next; }; 4.对于用户信息的查找,这里运用了以姓名和电话号码两种查找标准进行查找,链地址的存在使得冲突消除,同时查找实现。 5.清空的实现是设立了一个清空函数,是哈希表的所有成员内容为空,在主函数中进行调用,实现全部信息删除功能。 四、实验源代码 #include using namespace std; #include "string.h" #include "fstream" #define NULL 0 unsigned int key; unsigned int key2; int *p; struct node //建节点 { char name[8],address[20]; char num[11]; node * next; };

c语言课程设计--汉诺塔

课程设计报告 课程设计名称:C语言课程设计 课程设计题目:汉诺塔问题求解演示 院(系):计算机学院 专业:计算机科学与技术 班级: 学号: 姓名: 指导教师: 完成时间:2010年3月18日

沈阳航空航天大学课程设计报告 目录 第1章需求分析 (3) 1.1 课程设计的题目及要求 (3) 1.2 总体分析 (3) 第2章系统设计 (4) 2.1 主要函数和函数功能描述 (4) 2.2 功能模块图 (4) 第3章详细设计 (5) 3.1主函数流程图 (5) 3.2各功能模块具体流程图 (6) 第4章调试分析 (10) 4.1.调试初期 (10) 4.2.调试中期 (10) 4.3.调试后期 (10) 参考文献 (11) 附录 (12)

第1章需求分析 1.1 课程设计的题目及要求 题目:汉诺塔问题求解演示 内容: 在屏幕上绘出三根针,其中一根针上放着N个从大到小的盘子。要求将这些盘子从这根针经过一个过渡的针移到另外一根针上,移动的过程中大盘子不能压在小盘子上面,且一次只能移动一个盘子。要求形象直观地演示盘子移动的方案和过程。 要求: 1)独立完成系统的设计,编码和调试。 2)系统利用C语言实现。 3)安照课程设计规范书写课程设计报告。 4)熟练掌握基本的调试方法,并将程序调试通过 1.2总体分析 本题目需要使用C语言绘制图形,所以需要turbo C,需要绘图函数,而汉诺塔的函数属于经典的函数,在书本上都学习过,所以这个题目的难点在于需要绘制汉诺塔图形。攻克这一点其他的问题都迎刃而解。但是我个人以前也没有学过一些关于turboC 方面的知识。所以我将重点放在了对#include下的一系列绘图函数的研究与应用,对屏幕上的图像坐标分析是一个难点。其中用到了graphics.h头文件中的bar, outtextxy, setfillstyle,closegraph函数。进行了画图(利用bar函数进行画框的操作),填充颜色(利用setfillstyle函数填充白色和黑色,以分辨图形与图形背景),在特定位置输出特定字符等操作(利用outtextxy函数)。

哈希表的设计与实现-数据结构与算法课程设计报告

合肥学院 计算机科学与技术系 课程设计报告 2009 ~2010 学年第二学期 课程数据结构与算法 课程设计名称哈希表的设计与实现 学生姓名王东东 学号0804012030 专业班级08计本(2) 指导教师王昆仑、李贯虹 2010 年5 月

课程设计目的 “数据结构与算法课程设计”是计算机科学与技术专业学生的集中实践性环节之一, 是学习“数据结构与算法”理论和实验课程后进行的一次全面的综合练习。其目的是要达到 理论与实际应用相结合,提高学生组织数据及编写程序的能力,使学生能够根据问题要求和 数据对象的特性,学会数据组织的方法,把现实世界中的实际问题在计算机内部表示出来并 用软件解决问题,培养良好的程序设计技能。 一、问题分析和任务定义 1、问题分析 要完成如下要求:设计哈希表实现电话号码查询系统。 实现本程序需要解决以下几个问题: (1)如何定义一个包括电话号码、用户名、地址的节点。 (2)如何以电话号码和用户名为关键字建立哈希表。 (3)用什么方法解决冲突。 (4)如何查找并显示给定电话号码的记录。 (5)如何查找并显示给定用户名的记录。 2 任务定义 1、由问题分析知,本设计要求分别以电话号码和用户名为关键字建立哈希表,z在此基 础上实现查找功能。本实验是要我们分析怎么样很好的解决散列问题,从而建立一比较合理 的哈希表。由于长度无法确定,并且如果采用线性探测法散列算法,删除结点会引起“信息 丢失”的问题。所以采用链地址法散列算法。采用链地址法,当出现同义词冲突时,可以使 用链表结构把同义词链接在一起,即同义词的存储地址不是散列表中其他的空地址。 根据问题分析,我们可以定义有3个域的节点,这三个域分别为电话号码char num[30],姓名char name[30],地址char address[30]。这种类型的每个节点对应链表中的每个节点,其中电话号码和姓名可分别作关键字实现哈希表的创建。 二、数据结构的选择和概要设计 1、数据结构的选择 数据结构:散列结构。 散列结构是使用散列函数建立数据结点关键词与存储地址之间的对应关系,并提供多 种当数据结点存储地址发生“冲突”时的处理方法而建立的一种数据结构。 散列结构基本思想,是以所需存储的结点中的关键词作为自变量,通过某种确定的函 数H(称作散列函数或者哈希函数)进行计算,把求出的函数值作为该结点的存储地址,并 将该结点或结点地址的关键字存储在这个地址中。 散列结构法(简称散列法)通过在结点的存储地址和关键字之间建立某种确定的函数 关系H,使得每个结点(或关键字)都有一个唯一的存储地址相对应。 当需要查找某一指定关键词的结点时,可以很方便地根据待查关键字K计算出对应的“映像”H(K),即结点的存储地址。从而一次存取便能得到待查结点,不再需要进行若干次的 比较运算,而可以通过关键词直接计算出该结点的所在位置。

哈希表查找成功和不成功的算法

哈希表查找不成功怎么计算? 解答:先建好表,然后可以算出每个位置不成功时的比较次数之和,再除以表空间个数! 例如:散列函数为hash(x)=x MOD 13,用线性探测,建立了哈希表之后,如何求查找不成功时的平均查找长度!? 地址:0 1 2 3 4 5 6 7 8 9 10 11 12 数据: 39 1228154244 625-- 36- 38 成功次数: 1 3 1 2 2 1 191 1 不成功次数:98 7 65 4 3 2 1 1 2 110 查找成功时的平均查找长度:ASL=(1+3+1+2+2+1+1+9+1+1)/10 =2.2 查找不成功时的平均查找长度:ASL=(9+8+7+6+5+4+3+2+1+1+2+1+10)/13=4.54 说明: 第n个位置不成功时的比较次数为,第n个位置到第1个没有数据位置的距离。至少要查询多少次才能确认没有这个值。 (1)查询hash(x)=0,至少要查询9次遇到表值为空的时候,才能确认查询失 败。 (2)查询hash(x)=1,至少要查询8次遇到表值为空的时候,才能确认查询失 败。 (3)查询hash(x)=2,至少要查询7次遇到表值为空的时候,才能确认查询失 败。 (4)查询hash(x)=3,至少要查询6次遇到表值为空的时候,才能确认查询失 败。 (5)查询hash(x)=4,至少要查询5次遇到表值为空的时候,才能确认查询失 败。 (6)查询hash(x)=5,至少要查询4次遇到表值为空的时候,才能确认查询失 败。

(7)查询hash(x)=6,至少要查询3次遇到表值为空的时候,才能确认查询失败。 (8)查询hash(x)=7,至少要查询2次遇到表值为空的时候,才能确认查询失败。 (9)查询hash(x)=8,至少要查询1次遇到表值为空的时候,才能确认查询失败。 (10)查询hash(x)=9,至少要查询1次遇到表值为空的时候,才能确认查询失败。 (11)查询hash(x)=10,至少要查询2次遇到表值为空的时候,才能确认查询失败。 (12)查询hash(x)=11,至少要查询1次遇到表值为空的时候,才能确认查询失败。 (13)查询hash(x)=12,至少要查询10次遇到表值为空(循环查询顺序表)的时候,才能确认查询失败。 下面看下2010年2010年全国硕士研究生入学统一考试计算机科学与技术学科联考计算机学科专业基础综合试题中一个考哈希表的题。 Question1: 将关键字序列(7、8、30、11、18、9、14)散列存储到散列表中。散列表的存储空间是一个下标从0开始的一维数组,散列函数为:H(key) = (keyx3) MOD 7,处理冲突采用线性探测再散列法,要求装填(载)因子为0.7。 (1) 请画出所构造的散列表。 (2) 分别计算等概率情况下查找成功和查找不成功的平均查找长度。 Ans: (1).首先明确一个概念装载因子,装载因子是指所有关键子填充哈希表后饱和的程度,它等于关键字总数/哈希表的长度。根据题意,我们可以确定哈希表的长度为 L = 7/0.7 = 10;因此此题需要构建的哈希表是下标为0~9的一维数组。根据散列函数可以得到如下散列函数值表。 H(Key) = (keyx3) MOD 7, 例如key=7时, H(7) = (7x3)%7 = 21%7=0,其他关键字同理。

数据结构哈希查找源代码

数据结构哈希查找 源代码: #include #include using namespace std; #define SUCCESS 1; #define UNSUCCESS 0; #define NULLKEY -1; #define TableLength 13; #define p 13;// H(key)=key % p typedef int T; template struct ElemType { T key;//关键字 /* //其它 .... */ }; template class LHSearch { private: ElemType *HT; //开放定址哈希表 int count; //当前数据元素个数 int size; //哈希表长度 public: LHSearch(); // ~LHSearch(); // void InitHashTable(int n);// int Hash(T key); //计算哈希地址 void Collision(int &s);//冲突,计算下一个地址 int Search(T key,int &s);//哈希查找 int Insert(ElemType e); //元素插入 void Display(); //显示哈希表 }; template LHSearch::LHSearch()

{ HT=NULL; size=0; count=0; } template LHSearch::~LHSearch() { delete [] HT; count=0; } template int LHSearch::Hash(T key) {//由哈希函数求哈希地址 return key%p; } template void LHSearch::Collision(int &s) {//开放定址法解决冲突 s=s++; } template int LHSearch::Search(T key,int &s) {//查找,找到返回 //int s; s=Hash(key); while((HT[s].key!=-1) && (key!=HT[s].key)) Collision(s); if(HT[s].key==key) return 1; else return 0; } template int LHSearch::Insert(ElemType e) {//插入元素 int s; if(count==size) { cout<<"表满,不能插入!"<

汉诺塔非递归算法C语言实现

汉诺塔非递归算法C语言实现 #include #include #define CSZL 10 #define FPZL 10 typedef struct hanoi { int n; char x,y,z; }hanoi; typedef struct Stack { hanoi *base,*top; int stacksize; }Stack; int InitStack(Stack *S) { S->base=(hanoi *)malloc(CSZL*sizeof(hanoi)); if(!S->base) return 0; S->top=S->base; S->stacksize=CSZL; return 1; } int PushStack(Stack *S,int n,char x,char y,char z) { if(S->top-S->base==S->stacksize) { S->base=(hanoi *)realloc(S->base,(S->stacksize+FPZL)*sizeof(hanoi)); if(!S->base) return 0; S->top=S->base+S->stacksize; S->stacksize+=FPZL; } S->top->n=n; S->top->x=x; S->top->y=y; S->top->z=z; S->top++; return 1; } int PopStack(Stack *S,int *n,char *x,char *y,char *z) { if(S->top==S->base)

利用哈希技术统计C源程序关键字出现频度

:利用哈希技术统计C源程序关键字出现频度 目录一.需求分析说明 (3) 二.总体设计 (3) 三.详细设计 (4) 四.实现部分 (5) 五.程序测试 (10) 六.总结 (11)

一、需求分析说明 1.课程设计目的 本课程设计的目的就是要达到理论与实际应用相结合,使同学们能够根据数据对象的特性,学会数据组织的方法,能把现实世界中的实际问题在计算机内部表示出来,并培养基本的、良好的程序设计技能。 2.题目要求 1)题目内容: 利用Hash技术统计某个C源程序中的关键字出现的频度 2)基本要求: 扫描一个C源程序,用Hash表存储该程序中出现的关键字,并统计该程序中的关键字出现的频度。用线性探测法解决Hash冲突。设Hash函数为: Hash(key)[(key的第一个字母序号)*100+(key的最后一个字母序号)] MOD 41 二、总体设计 一.算法思想描述 首先读取关键字文件以建立二叉排序树以供后续查询,每个树节点保存一个关键字字符串及指向左右子树的指针。同时创建一Hash表,每个节点除应保存关键字字符串外,还应保存关键字频数及该存储单元冲突次数。然后扫描一个C源程序,每次扫描一行,从中循环分离出每个单词,每次均查找其是否为关键字,若是,则按计算公式计算其KEY值并在Hash表中进行相应操作,若该节点为空则插入否者比较其是否与现有关键字相同,若相

同则增加其频数,否则增加其冲突次数并继续线性探测下一个存储单元,完了继续操作下一个分离出来的单词,如此循环运行直至扫描结束。编写本程序时,使用了二叉树创建、二叉树查找、Hash表的建立和操作及文件操作等基本算法。 二.三、详细设计 (程序结构 //Hash表存储结构 typedef struct node //定义 { char s[20]; int num,time; //num为频数,time为冲突次数 }node; //二叉排序树结构定义 typedef struct nod //定义 { char s[20]; struct nod *left,*right; }nod; int max;//max为Hash表长度

数据结构课程设计--哈希表实验报告

福建工程学院 课程设计 课程:算法与数据结构 题目:哈希表 专业:网络工程 班级:xxxxxx班 座号:xxxxxxxxxxxx 姓名:xxxxxxx 2011年12 月31 日 实验题目:哈希表 一、要解决的问题 针对同班同学信息设计一个通讯录,学生信息有姓名,学号,电话号码等。以学生姓名为关键字设计哈希表,并完成相应的建表和查表程序。 基本要求:姓名以汉语拼音形式,待填入哈希表的人名约30个,自行设计哈希函数,用线性探测再散列法或链地址法处理冲突;在查找的过程中给出比较的次数。完成按姓名查询的操作。 运行的环境:Microsoft Visual C++ 6.0 二、算法基本思想描述 设计一个哈希表(哈希表内的元素为自定义的结构体)用来存放待填入的30个人名,人名为中国姓名的汉语拼音形式,用除留余数法构造哈希函数,用线性探查法解决哈希冲突。建立哈希表并且将其显示出来。通过要查找的关键字用哈希函数计算出相应的地址来查找人名。通过循环语句调用数组中保存的数据来显示哈希表。 三、设计 1、数据结构的设计和说明 (1)结构体的定义 typedef struct //记录 { NA name; NA xuehao; NA tel; }Record;

{ Record *elem[HASHSIZE]; //数据元素存储基址 int count; //当前数据元素个数 int size; //当前容量 }HashTable; 哈希表元素的定义,包含数据元素存储基址、数据元素个数、当前容量。 2、关键算法的设计 (1)姓名的折叠处理 long fold(NA s) //人名的折叠处理 { char *p; long sum=0; NA ss; strcpy(ss,s); //复制字符串,不改变原字符串的大小写 strupr(ss); //将字符串ss转换为大写形式 p=ss; while(*p!='\0') sum+=*p++; printf("\nsum====================%d",sum); return sum; } (2)建立哈希表 1、用除留余数法构建哈希函数 2、用线性探测再散列法处理冲突 int Hash1(NA str) //哈希函数 { long n; int m; n=fold(str); //先将用户名进行折叠处理 m=n%HASHSIZE; //折叠处理后的数,用除留余数法构造哈希函数 return m; //并返回模值 }Status collision(int p,int c) //冲突处理函数,采用二次探测再散列法解决冲突{ int i,q; i=c/2+1; while(i=0) return q; else i=c/2+1; } else{ q=(p-i*i)%HASHSIZE; c++;

相关文档
最新文档