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

合集下载

数据结构实验-实验指导书

数据结构实验-实验指导书

实验一线性表操作一、实验目的1熟悉并掌握线性表的逻辑结构、物理结构。

2熟悉并掌握顺序表的存储结构、基本操作和具体的函数定义。

3熟悉VC++程序的基本结构,掌握程序中的用户头文件、实现文件和主文件之间的相互关系及各自的作用。

4熟悉VC++操作环境的使用以及多文件的输入、编辑、调试和运行的全过程。

二、实验要求1实验之前认真准备,编写好源程序。

2实验中认真调试程序,对运行结果进行分析,注意程序的正确性和健壮性的验证。

3不断积累程序的调试方法。

三、实验内容基本题:1对元素类型为整型的顺序存储的线性表进行插入、删除和查找操作。

加强、提高题:2、编写一个求解Josephus问题的函数。

用整数序列1, 2, 3, ……, n表示顺序围坐在圆桌周围的人。

然后使用n = 9, s = 1, m = 5,以及n = 9, s = 1, m = 0,或者n = 9, s = 1, m = 10作为输入数据,检查你的程序的正确性和健壮性。

最后分析所完成算法的时间复杂度。

定义JosephusCircle类,其中含完成初始化、报数出圈成员函数、输出显示等方法。

(可以选做其中之一)加强题:(1)采用数组作为求解过程中使用的数据结构。

提高题:(2)采用循环链表作为求解过程中使用的数据结构。

运行时允许指定任意n、s、m数值,直至输入n = 0退出程序。

实验二栈、队列、递归应用一、实验目的1熟悉栈、队列这种特殊线性结构的特性2熟练掌握栈、队列在顺序存储结构和链表存储结构下的基本操作。

二、实验要求1实验之前认真准备,编写好源程序。

2实验中认真调试程序,对运行结果进行分析,注意程序的正确性和健壮性的验证。

3不断积累程序的调试方法。

三、实验内容基本题(必做):1分别就栈的顺序存储结构和链式存储结构实现栈的各种基本操作。

2、假设以带头结点的循环链表表示队列,并且只设一个指针指向对尾结点,不设头指针,试设计相应的置队空、入队和出队的程序。

加强题:3设线性表A中有n个字符,试设计程序判断字符串是否中心对称,例如xyzyx和xyzzyx都是中心对称的字符串。

数据结构与算法实验报告5-查找与排序

数据结构与算法实验报告5-查找与排序

北京物资学院信息学院实验报告
课程名_数据结构与算法
实验名称查找与排序
实验日期年月日实验报告日期年月日姓名______ ___ 班级_____ ________ 学号___
一、实验目的
1.掌握线性表查找的方法;
2.了解树表查找思想;
3.掌握散列表查找的方法.
4.掌握插入排序、交换排序和选择排序的思想和方法;
二、实验内容
查找部分
1.实现顺序查找的两个算法(P307), 可以完成对顺序表的查找操作, 并根据查到和未查到两种情况输出结果;
2.实现对有序表的二分查找;
3.实现散列查找算法(链接法),应能够解决冲突;
排序部分
4.分别实现直接插入排序、直接选择排序、冒泡排序和快速排序算法
三、实验地点与环境
3.1 实验地点
3.2实验环境
(操作系统、C语言环境)
四、实验步骤
(描述实验步骤及中间的结果或现象。

在实验中做了什么事情, 怎么做的, 发生的现象和中间结果, 给出关键函数和主函数中的关键段落)
五、实验结果
六、总结
(说明实验过程中遇到的问题及解决办法;个人的收获;未解决的问题等)。

C语言数据结构线性表的基本操作实验报告

C语言数据结构线性表的基本操作实验报告

实验一线性表的基本操作一、实验目的与基本要求1.掌握数据结构中的一些基本概念。

数据、数据项、数据元素、数据类型和数据结构,以及它们之间的关系。

2.了解数据的逻辑结构和数据的存储结构之间的区别与联系;数据的运算与数据的逻辑结构的关系。

3.掌握顺序表和链表的基本操作:插入、删除、查找以及表的合并等运算。

4.掌握运用C语言上机调试线性表的基本方法。

二、实验条件1.硬件:一台微机2.软件:操作系统和C语言系统三、实验方法确定存储结构后,上机调试实现线性表的基本运算。

四、实验内容1.建立顺序表,基本操作包括:初始化,建立一个顺序存储的链表,输出顺序表,判断是否为空,取表中第i个元素,定位函数(返回第一个与x相等的元素位置),插入,删除。

2.建立单链表,基本操作包括:初始化,建立一个链式存储的链表,输出顺序表,判断是否为空,取表中第i个元素,定位函数(返回第一个与x相等的元素位置),插入,删除。

3.假设有两个按数据元素值非递减有序排列的线性表A和B,均以顺序表作为存储结构。

编写算法将A表和B表归并成一个按元素值非递增有序(允许值相同)排列的线性表C。

(可以利用将B中元素插入A中,或新建C表)4.假设有两个按数据元素值非递减有序排列的线性表A和B,均以单链表作为存储结构。

编写算法将A表和B表归并成一个按元素值递减有序(即非递增有序,允许值相同)排列的线性表C。

五、附源程序及算法程序流程图1.源程序(1)源程序(实验要求1和3)#include<stdio.h>#include<malloc.h>#include<stdlib.h>#define LIST_INIT_SIZE 100#define LISTINCREMENT 10typedef struct arr{int * elem;int length;int listsize;}Sqlist;void menu(); //菜单void InitList(Sqlist *p); // 创建线性表void ShowList(Sqlist *p); // 输出顺序线性表void ListDelete(Sqlist *p,int i,int &e); // 在顺序线性表中删除第i个元素,并用e返回其值void ListInsert(Sqlist *p); // 在顺序线性表中第i个元素前插入新元素evoid ListEmpty(Sqlist *p); // 判断L是否为空表void GetList(Sqlist *p,int i,int &e); // 用e返回L中第i个数据元素的值void ListInsert(Sqlist *p,int i,int e);bool compare(int a,int b);void LocateElem(Sqlist *L,int e); // 在顺序线性表L中查找第1个值与e满足compare()d元素的位序void MergeList_L(Sqlist *La,Sqlist *Lb); // 归并void main(){Sqlist La;Sqlist Lb;int n,m,x;menu();scanf("%d",&n);while(n){switch(n){case 0: ; break;case 1:InitList(&La);break;case 2:ListEmpty(&La);break;case 3:printf("请输入插入的位序:\n");scanf("%d",&m);printf("请出入要插入的数:\n");scanf("%d",&x);ListInsert(&La,m,x);break;case 4:printf("请输入删除元素的位序:\n");scanf("%d",&m);ListDelete(&La,m,x);printf("删除的元素为:%d\n",x);break;case 5:printf("请输入要找的与线性表中相等的数:\n");scanf("%d",&m);LocateElem(&La,m);break;case 6:printf("请输入查找的位序:\n");scanf("%d",&m);GetList(&La,m,x);printf("La中第%d个元素的值为%d\n",m,x);break;case 7:ShowList(&La);break;case 8:InitList(&Lb);break;case 9:MergeList_L(&La,&Lb);printf("归并成功!");break;}menu();scanf("%d",&n);}}/*菜单*/void menu(){printf("********************\n\n");printf(" 0.退出\n\n");printf(" 1.创建线性表La\n\n");printf(" 2.判断La是否为空表\n\n");printf(" 3.插入元素(La)\n\n");printf(" 4.删除元素(La)\n\n");printf(" 5.定位元素(La)\n\n");printf(" 6.取元素(La)\n\n");printf(" 7.输出线性表\n\n");printf(" 8.创建线性表Lb\n\n");printf(" 9.归并为一个线性表La\n\n");printf("********************\n\n");}/*创建顺序线性表L*/void InitList(Sqlist *L){int n;int i=0;L->elem=(int *)malloc(LIST_INIT_SIZE*sizeof(int));if(NULL==L->elem)printf("储存分配失败!\n");else{L->length=0;L->listsize=LIST_INIT_SIZE;printf("输入顺序表a:\n");scanf("%d",&n);while(n){L->elem[i]=n;i++;L->length++;L->listsize=L->listsize-4;scanf("%d",&n);}}}/*输出顺序线性表*/void ShowList(Sqlist *p){int i;if(0==p->length)printf("数组为空!\n");elsefor(i=0;i<p->length;i++)printf("%d ",p->elem[i]);printf("\n");}/*判断L是否为空表*/void ListEmpty(Sqlist *p)if(0==p->length)printf("L是空表!\n");elseprintf("L不是空表!\n");}/*在顺序线性表中第i个元素前插入新元素e */void ListInsert(Sqlist *p,int i,int e){int *newbase;int *q1;int *q2;while(i<1||i>p->length+1){printf("您输入的i超出范围!\n请重新输入要插入的位置\n:");scanf("%d",&i);}if(p->length>=p->listsize){newbase=(int *)realloc(p->elem,(p->listsize+LISTINCREMENT)*sizeof(int));if(!newbase)exit(0);else{p->elem=newbase;p->listsize+=LISTINCREMENT;}}q1=&(p->elem[i-1]);for(q2=&(p->elem[p->length-1]);q2>=q1;--q2)*(q2+1)=*q2;*q1=e;++p->length;}/*/在顺序线性表中删除第i个元素,并用e返回其值*/void ListDelete(Sqlist *p,int i,int &e){int *q1,*q2;while(i<1||i>p->length){printf("您输入的i超出范围!请重新输入:");scanf("%d",&i);}q1=&(p->elem[i-1]);e=*q1;q2=p->elem+p->length-1;for(++q1;q1<=q2;++q1)*(q1-1)=*q1;--p->length;}/*对比a与b相等*/bool compare(int a,int b){if(a==b)return 1;elsereturn 0;}/*在顺序线性表L中查找第1个值与e满足compare()d元素的位序*/ void LocateElem(Sqlist *L,int e){int i=1;int *p;p=L->elem;while(i<=L->length && !compare(*p++,e))++i;if(i<=L->length)printf("第1个与e相等的元素的位序为%d\n",i);elseprintf("没有该元素!\n");}/*用e返回L中第i个数据元素的值*/void GetList(Sqlist *p,int i,int &e){Sqlist *p1;p1=p;e=p1->elem[i-1];}/* 已知顺序线性表La和Lb是元素按值非递减排列*//* 把La和Lb归并到La上,La的元素也是按值非递减*/void MergeList_L(Sqlist *La,Sqlist *Lb){int i=0,j=0,k,t;int *newbase;Sqlist *pa,*pb;pa=La;pb=Lb;while(i<pa->length && j<pb->length){if(pa->elem[i] >= pb->elem[j]){if(pa->listsize==0){newbase=(int*)realloc(pa->elem,(pa->listsize+LISTINCREMENT)*sizeof(int));if(!newbase)exit(0);}for(k=pa->length-1; k>=i; k--)pa->elem[k+1]=pa->elem[k];pa->length++;pa->elem[i]=pb->elem[j];i++;j++;}elsei++;}while(j<pb->length){if( pa->listsize < pb->length-j ){newbase=(int*)realloc(pa->elem,(pa->listsize+LISTINCREMENT)*sizeof(int));if(!newbase)exit(0);}for(j;j<pb->length;j++,i++){pa->elem[i]=pb->elem[j];pa->length++;}}for(i=0;i<pa->length/2;i++){t=pa->elem[i];pa->elem[i]=pa->elem[pa->length-i-1];pa->elem[pa->length-i-1]=t;}}(2)源程序(实验要求2和4)#include<stdio.h>#include<malloc.h>#include<stdlib.h>typedef struct LNode{int data;struct LNode *next;}LNode, *LinkList;void menu();LinkList InitList();void ShowList(LinkList L);void ListDelete(LinkList L,int i,int &e);void ListEmpty(LinkList L);void GetList(LinkList L,int i,int &e);void ListInsert(LinkList L,int i,int e);bool compare(int a,int b);void LocateElem(LinkList L,int e);LinkList MergeList_L(LinkList La,LinkList Lb);int total=0;void main(){LinkList La;LinkList Lb;La=(LinkList)malloc(sizeof(struct LNode));La->next=NULL;Lb=(LinkList)malloc(sizeof(struct LNode));Lb->next=NULL;int n;int m;int x;menu();scanf("%d",&n);while(n){switch(n){case 0: ; break;case 1:La->next=InitList();break;case 2:ListEmpty(La);break;case 3:printf("请输入要插入到第几个节点前:\n");scanf("%d",&m);printf("请输入插入的数据:\n");scanf("%d",&x);ListInsert(La,m,x);break;case 4:printf("请输入删除元素的位序:\n");scanf("%d",&m);ListDelete(La,m,x);printf("删除的元素为:%d\n",x);break;case 5:printf("请输入要找的与线性表中相等的数:\n");scanf("%d",&m);LocateElem(La,m);break;case 6:printf("请输入查找的位序:\n");scanf("%d",&m);GetList(La,m,x);printf("La中第%d个元素的值为%d\n",m,x);break;case 7:ShowList(La);break;case 8:Lb->next=InitList();break;case 9:La=MergeList_L(La,Lb);printf("归并成功\n");break;}menu();scanf("%d",&n);}}void menu(){printf("********************\n\n");printf(" 0.退出\n\n");printf(" 1.创建线性表La\n\n");printf(" 2.判断是否为空表\n\n");printf(" 3.插入元素\n\n");printf(" 4.删除元素\n\n");printf(" 5.定位元素\n\n");printf(" 6.取元素\n\n");printf(" 7.输出线性表\n\n");printf(" 8.创建线性表Lb\n\n");printf(" 9.归并两线性表\n\n");printf("********************\n\n");}// 创建链式线性表LLinkList InitList(){int count=0;LinkList pHead=NULL;LinkList pEnd,pNew;pEnd=pNew=(LinkList)malloc(sizeof(struct LNode));printf("请输入数据:\n");scanf("%d",&pNew->data);while(pNew->data){count++;if(count==1){pNew->next=pHead;pEnd=pNew;pHead=pNew;}else{pNew->next=NULL;pEnd->next=pNew;pEnd=pNew;}pNew=(LinkList)malloc(sizeof(struct LNode));printf("请输入数据:\n");scanf("%d",&pNew->data);}free(pNew);total=total+count;return pHead;}// 判断L是否为空表void ListEmpty(LinkList L){if(NULL==L->next)printf("此表为空表!\n");elseprintf("此表不为空表!\n");}// 在链式线性表中第i个元素前插入新元素e void ListInsert(LinkList L,int i,int e){LinkList p;LinkList s;p=L;int j=0;while(p&&j<i-1){p=p->next;++j;}if(!p||j>i-1)printf("不存在您要找的节点!\n");else{s=(LinkList)malloc(sizeof(int));s->data=e;s->next=p->next;p->next=s;printf("插入节点成功!\n");}}// 输出链式线性表void ShowList(LinkList L){LinkList p;p=L->next;if(p==NULL)printf("此表为空表!\n");elsewhile(p){printf("%d ",p->data);p=p->next;}printf("\n");}// 在链式线性表中删除第i个元素,并用e返回其值void ListDelete(LinkList L,int i,int &e){LinkList p;LinkList q;p=L;int j=0;while(p->next && j<i-1){p=p->next;++j;}if(!(p->next)||j>i-1)printf("没有找到要删除的位置!");else{q=p->next;p->next=q->next;e=q->data;free(q);}}// 用e返回L中第i个数据元素的值void GetList(LinkList L,int i,int &e){LinkList p;p=L->next;int j=0;while(p->next && j<i-1){p=p->next;++j;}if(!(p)||j>i-1)printf("没有找到要查找的位置!");elsee=p->data;}// 对比a与b相等bool compare(int a,int b){if(a==b)return 1;elsereturn 0;}// 在链式线性表L中查找第1个值与e满足compare()d元素的位序void LocateElem(LinkList L,int e){int i=0;LinkList p;p=L;while(p->next && !compare(p->data,e)){p=p->next;i++;}if(NULL==p->next){if(0==compare(p->data,e))printf("没有该元素!\n");elseprintf("第1个与e相等的元素的位序为%d\n",i);}elseif(compare(p->data,e))printf("没有该元素!\n");}LinkList MergeList_L(LinkList La,LinkList Lb){int i,j,k;LinkList pa_1,pb_1,pa_2,pb_2,pc,pd;pa_1=La->next;pc=pa_2=La;pb_1=pb_2=Lb->next;if(pa_1->data > pb_1->data){pc=pa_2=Lb;pa_1=Lb->next;pb_1=pb_2=La->next;}while(pa_1 && pb_1){if(pa_1->data >= pb_1->data){pa_2->next=pb_1;pb_2=pb_1->next;pb_1->next=pa_1;pb_1=pb_2;pa_2=pa_2->next;}else{pa_1=pa_1->next;pa_2=pa_2->next;}}if(pb_1)pa_2->next=pb_1;pd=(LinkList)malloc(sizeof(struct LNode));pd->next=NULL;pa_2=pd;k=total;for(i=0;i<total;i++){pa_1=pc->next;for(j=1;j<k;j++)pa_1=pa_1->next;pb_1=(LinkList)malloc(sizeof(struct LNode));pa_2->next=pb_1;pa_2=pa_2->next;pa_2->data=pa_1->data;k--;}pa_2->next=NULL;return pd;}2.流程图(实验要求1和3)图1 主函数流程图图2创建线性表La流程图图3判断La是否为空表流程图图4 插入元素(La)流程图图5删除元素(La)流程图图6定位元素(La)流程图图7取元素(La)流程图图8输出线性表流程图图9输出线性表流程图流程图(实验要求2和4)图10主函数流程图图11创建线性表La流程图图12判断是否为空表流程图图13插入元素流程图图14删除元素流程图图15定位元素流程图图图16取元素流程图图17创建Lb流程图图18归并两表流程图六、运行结果1. (实验要求1和3)点击运行,首先出现的是菜单界面,选择菜单选项进行操作,如图所示。

c实现的hash表-概述说明以及解释

c实现的hash表-概述说明以及解释

c实现的hash表-概述说明以及解释1.引言1.1 概述在计算机科学中,哈希表(Hash Table),又被称为散列表,是一种常用的数据结构。

它能够以常数时间复杂度(O(1))来实现插入、删除和查找等操作,因此具有高效的特性。

哈希表通过哈希函数将键(key)映射到一个固定大小的数组(通常称为哈希表)。

通过这种映射关系,我们可以在数组中快速访问到对应的值(value)。

常见的应用场景包括缓存系统、数据库索引、编译器符号表等。

相对于其他数据结构,哈希表具有以下优点:1. 高效的插入、删除和查找操作:哈希表在插入、删除和查找数据时以常数时间复杂度进行操作,无论数据量大小,都能快速地完成操作。

2. 高效的存储和检索:通过哈希函数的映射关系,哈希表能够将键值对存储在数组中,可以通过键快速地找到对应的值。

3. 空间效率高:哈希表通过哈希函数将键映射到数组下标,能够充分利用存储空间,避免冗余的存储。

然而,哈希表也存在一些局限性:1. 冲突问题:由于哈希函数的映射关系是将多个键映射到同一个数组下标上,可能会导致冲突。

解决冲突问题的常见方法包括链地址法(Chaining)和开放定址法(Open Addressing)等。

2. 内存消耗:由于哈希表需要维护额外的空间来存储映射关系,所以相比于其他数据结构来说,可能会占用较多的内存。

本篇长文将重点介绍C语言实现哈希表的方法。

我们将首先讨论哈希表的定义和实现原理,然后详细介绍在C语言中如何实现一个高效的哈希表。

最后,我们将总结哈希表的优势,对比其他数据结构,并展望哈希表在未来的发展前景。

通过本文的学习,读者将能够深入理解哈希表的底层实现原理,并学会如何在C语言中利用哈希表解决实际问题。

1.2 文章结构本文将围绕C语言实现的hash表展开讨论,并按照以下结构进行组织。

引言部分将对hash表进行概述,介绍hash表的基本概念、作用以及其在实际应用中的重要性。

同时,引言部分还会阐述本文的目的,即通过C语言实现的hash表,来探讨其实现原理、方法以及与其他数据结构的对比。

c语言版数据结构试题及答案

c语言版数据结构试题及答案

习题一一、单选题1.在一个带有附加表头结点的单链表HL中,若要向表头插入一个由指针p指向的结点,则执行( B )。

A. HL=p; p->next=HL;B. p->next=HL->next; HL->next=p;C. p->next=HL; p=HL;D. p->next=HL; HL=p;2.若顺序存储的循环队列的QueueMaxSize=n,则该队列最多可存储( B )个元素.A. nB.n-1C. n+1D.不确定3.下述哪一条是顺序存储方式的优点?(A )A.存储密度大 B.插入和删除运算方便C. 获取符合某种条件的元素方便D.查找运算速度快4.设有一个二维数组A[m][n],假设A[0][0]存放位置在600(10),A[3][3]存放位置在678(10),每个元素占一个空间,问A[2][3](10)存放在什么位置?(脚注(10)表示用10进制表示,m>3)DA.658 B.648 C.633 D.6535.下列关于二叉树遍历的叙述中,正确的是( AD ) 。

A. 若一个树叶是某二叉树的中序遍历的最后一个结点,则它必是该二叉树的前序遍历最后一个结点B.若一个点是某二叉树的前序遍历最后一个结点,则它必是该二叉树的中序遍历的最后一个结点 C.若一个结点是某二叉树的中序遍历的最后一个结点,则它必是该二叉树的前序最后一个结点D.若一个树叶是某二叉树的前序最后一个结点,则它必是该二叉树的中序遍历最后一个结点6.k层二叉树的结点总数最多为( A ).A.2k-1 B.2K+1 C.2K-1 D. 2k-17.对线性表进行二分法查找,其前提条件是( B ).A.线性表以链接方式存储,并且按关键码值排好序B.线性表以顺序方式存储,并且按关键码值的检索频率排好序C.线性表以顺序方式存储,并且按关键码值排好序D.线性表以链接方式存储,并且按关键码值的检索频率排好序8.对n个记录进行堆排序,所需要的辅助存储空为Cn) B. O(n) C. O(1) D. O(n2)A. O(1og29.对于线性表(7,34,77,25,64,49,20,14)进行散列存储时,若选用H(K)=K %7作为散列函数,则散列地址为0的元素有( D )个,A.1 B.2 C.3 D.410.下列关于数据结构的叙述中,正确的是( D ).A.数组是不同类型值的集合B.递归算法的程序结构比迭代算法的程序结构更为精炼C.树是一种线性结构D.用一维数组存储一棵完全二叉树是有效的存储方法二、填空题1.数据的逻辑结构被分为_集合结构、__线性结构、_树结构和_图结构四种。

数据结构课程设计-利用散列表做一个电话号码查找系统

数据结构课程设计-利用散列表做一个电话号码查找系统

数据结构课程设计-利⽤散列表做⼀个电话号码查找系统【基本要求】(1)设每个记录有下列数据项:电话号码、⽤户名、地址;(2)从键盘输⼊各记录,分别以电话号码和⽤户名为关键字建⽴散列表;(3)采⽤⼀定的⽅法解决冲突;(4)查找并显⽰给定电话号码的记录;(5)查找并显⽰给定⽤户名的记录。

【选做内容】(1)系统功能的完善;(2)设计不同的散列函数,⽐较冲突率; (3)在散列函数确定的前提下,尝试各种不同类型处理冲突的⽅法,考察平均查找长度的变化。

⽤的C++开发,基本实现了3种哈希函数+3种解决冲突的⽅法。

因为要求同时有姓名散列与按号码散列,所以⽤了flag标记每次的散列类型,针对不同的要求对散列函数做了个别优化。

哈希表类的结构如下1class HashTable{2public:3 HashTable(int size = MAXSIZE-1);4 ~HashTable(){ delete[]E; delete[]tag; delete[]E2; delete[]tag2; }5int hash1(string name, int flag);//哈希函数1 除数求余法6int hash2(string tel);//哈希函数2 折叠法7int hash3(string tel);//哈希函数3 数字分析法8int solve1(int hashVal, int flag);//线性探测法解决冲突9int solve2(int hashVal, int flag);//⼆次探测法解决冲突10 Node* solve3(int hashVal, int flag);//拉链法解决冲突11 User input();//往电话薄中添加⽤户12void creat(int flag); //创建散列表13void show(int flag); //列出电话薄所有元素14void search(int flag,string at); //搜索指定⽤户15void searchByNode(int flag, string at); //拉链法搜索指定⽤户16void insert(int flag, User newUser); //插⼊17void del(int flag, string by);//删除18void save(int flag);//将电话薄保存⾄本地⽂件19int length; //要创建的电话本长度20 Node** ht;21private:22 User* E; //⽤户数组按姓名散列23 User* E2; //⽤户数组2 按电话号码散列24int* tag; //标记散列表1每个桶的存储状态 0为空 1为实25int* tag2;//标记散列表2每个桶的存储状态26int flag; //1表⽰是按姓名 2表⽰按电话号码新建的哈希表27int maxSize; //哈希表最⼤长度28int f;//⽐例因⼦主要⽤于折叠法29 };View CodeUser类的结构class User{public:string name;string tel;string address;bool operator==(const User&target){if (this->name == &&this->address == target.address&&this->tel == target.tel)return true;elsereturn false;}};哈希函数1int HashTable::hash1(string name,int flag) //除留求余法{int hashValue; long a = 0;switch (flag){case1:for (int i = 0; i < name.length(); i++)a += int(name[i]);hashValue = a%maxSize;break;case2:int temp = atof(name.c_str());hashValue = temp%maxSize;break;}return hashValue;};哈希函数2int HashTable::hash2(string tel) //折叠法--移位法{int hashValue;int temp; //移位法求和temp = atof(tel.substr(0, 3).c_str()) + atof(tel.substr(3, 3).c_str())+ atof(tel.substr(6, 3).c_str()) + atof(tel.substr(9, 2).c_str());//取计算之后的数的最后三位if (temp >= 999){char p[10];sprintf(p, "%d", temp);string lastThree = p;lastThree = lastThree.substr(lastThree.length() - 3, 3);hashValue = atof(lastThree.c_str());return hashValue;}hashValue = temp;return hashValue;};哈希函数3int HashTable::hash3(string tel)//数字分析法做哈希函数{int hashValue;hashValue = atof(tel.substr(8, 3).c_str()); //因为电话号码⼀般后4位不同return hashValue;};解决冲突的⽅法1.线性探测法int HashTable::solve1(int hashVal,int flag) //线性探查法处理冲突{int output = hashVal;switch (flag){case1:for (int j = 1; j < MAXSIZE; j++){output = (hashVal + j) % MAXSIZE;if (tag[output] == 0){tag[output] = 1;return output;}}return -1;break;case2:for (int j = 1; j < MAXSIZE; j++){output = (hashVal + j) % MAXSIZE;if (tag2[output] == 0){tag2[output] = 1;return output;}}return -1;default:break;}};2.⼆次探查法int HashTable::solve2(int hashVal, int flag) //⼆次探查法解决冲突{int i = hashVal; //i为初始桶号int k = 0; //k为探查次数int odd = 0; //odd为控制加减的标志int save; //缓存上⼀次的桶号switch (flag){case1:while (tag[i]==1){if (odd == 0){k++; save = i;i = (i + 2 * k-1) % MAXSIZE;odd = 1;}else{i = (save - 2 * k+1) % MAXSIZE;odd = 0;if (i<0){i = i + MAXSIZE;}}}return i;break;case2:while (tag2[i] == 1){if (odd == 0){k++; save = i;i = (i + 2 * k - 1) % MAXSIZE;odd = 1;}else{k++;i = (save - 2 * k + 1) % MAXSIZE;odd = 0;if (i<0){i = i + MAXSIZE;}}}return i;break;default:break;}};3.拉链法Node* HashTable::solve3(int hashVal, int flag)//拉链法解决冲突{int i = hashVal; //第i条链Node*p = ht[i]; //该链上的头指针while (p!=NULL)p = p->next;//往后遍历直到找到⼀个空节点⽤于存放userreturn p;};所有代码如下1 #include <iostream>2 #include <string>3 #include <fstream>45using namespace std;67const int MAXSIZE = 12;//默认最⼤表长89101112//存储项13class User{14public:15string name;16string tel;17string address;18bool operator==(const User&target)19 {20if (this->name == &&this->address == target.address&&this->tel == target.tel) 21return true;22else23return false;24 }25 };2627//⽤于拉链法28struct Node{29 User user;30 Node* next;31 };32class HashTable{33public:34 HashTable(int size = MAXSIZE-1);35 ~HashTable(){ delete[]E; delete[]tag; delete[]E2; delete[]tag2; }36int hash1(string name, int flag);//哈希函数1 除数求余法37int hash2(string tel);//哈希函数2 折叠法38int hash3(string tel);//哈希函数3 数字分析法39int solve1(int hashVal, int flag);//线性探测法解决冲突40int solve2(int hashVal, int flag);//⼆次探测法解决冲突41 Node* solve3(int hashVal, int flag);//拉链法解决冲突42 User input();//往电话薄中添加⽤户43void creat(int flag); //创建散列表44void show(int flag); //列出电话薄所有元素45void search(int flag,string at); //搜索指定⽤户46void searchByNode(int flag, string at); //拉链法搜索指定⽤户47void insert(int flag, User newUser); //插⼊48void del(int flag, string by);//删除49void save(int flag);//将电话薄保存⾄本地⽂件50int length; //要创建的电话本长度51 Node** ht;52private:53 User* E; //⽤户数组按姓名散列54 User* E2; //⽤户数组2 按电话号码散列55int* tag; //标记散列表1每个桶的存储状态 0为空 1为实56int* tag2;//标记散列表2每个桶的存储状态57int flag; //1表⽰是按姓名 2表⽰按电话号码新建的哈希表58int maxSize; //哈希表最⼤长度59int f;//⽐例因⼦主要⽤于折叠法60 };6162 HashTable::HashTable(int size)63 {64 maxSize = size; //⽤作除数65 E = new User[MAXSIZE];66 E2 = new User[MAXSIZE];67 tag = new int[MAXSIZE];68 tag2 = new int[MAXSIZE];69for (int i = 0; i < MAXSIZE; i++)70 {71 tag[i] = 0;72 tag2[i] = 0;73 }74 f = maxSize / 512; //⽤于折叠法产⽣的哈希值过⼤保留3位数的地址范围为0~51175 ht = new Node*[maxSize]; //存放节点的⼀维数组拉链法76 };7778int HashTable::hash1(string name,int flag) //除数求余法79 {80int hashValue; long a = 0;81switch (flag)82 {83case1:84for (int i = 0; i < name.length(); i++)85 a += int(name[i]);86 hashValue = a%maxSize;87break;88case2:89int temp = atof(name.c_str());90 hashValue = temp%maxSize;91break;9293 }94return hashValue;95 };9697int HashTable::hash2(string tel) //折叠法--移位法98 {99int hashValue;100int temp; //移位法求和101 temp = atof(tel.substr(0, 3).c_str()) + atof(tel.substr(3, 3).c_str())102 + atof(tel.substr(6, 3).c_str()) + atof(tel.substr(9, 2).c_str());103//取计算之后的数的最后三位104if (temp >= 999)105 {106char p[10];107 sprintf(p, "%d", temp);108string lastThree = p;109 lastThree = lastThree.substr(lastThree.length() - 3, 3);110 hashValue = atof(lastThree.c_str());111return hashValue;112 }113 hashValue = temp;114return hashValue;115 };116117int HashTable::hash3(string tel)//数字分析法做哈希函数118 {119int hashValue;120 hashValue = atof(tel.substr(8, 3).c_str()); //因为电话号码⼀般后4位不同121return hashValue;122 };123124int HashTable::solve1(int hashVal,int flag) //线性探查法处理冲突125 {126int output = hashVal;127switch (flag)128 {129case1:130for (int j = 1; j < MAXSIZE; j++)131 {132 output = (hashVal + j) % MAXSIZE;133if (tag[output] == 0)134 {135 tag[output] = 1;136return output;137 }138 }139return -1;140break;141case2:142for (int j = 1; j < MAXSIZE; j++)143 {144 output = (hashVal + j) % MAXSIZE;145if (tag2[output] == 0)146 {147 tag2[output] = 1;148return output;149 }150 }151return -1;152default:153break;154 }155156 };157158int HashTable::solve2(int hashVal, int flag) //⼆次探查法解决冲突159 {160int i = hashVal; //i为初始桶号161int k = 0; //k为探查次数162int odd = 0; //odd为控制加减的标志163int save; //缓存上⼀次的桶号164switch (flag)165 {166case1:167while (tag[i]==1)168 {169if (odd == 0)170 {171 k++; save = i;172 i = (i + 2 * k-1) % MAXSIZE;173 odd = 1;174 }175else176 {177 i = (save - 2 * k+1) % MAXSIZE;178 odd = 0;179if (i<0)180 {181 i = i + MAXSIZE;182 }183 }184 }185return i;186break;187case2:188while (tag2[i] == 1)189 {190if (odd == 0)191 {192 k++; save = i;193 i = (i + 2 * k - 1) % MAXSIZE;194 odd = 1;195 }196else197 {198 k++;199 i = (save - 2 * k + 1) % MAXSIZE;200 odd = 0;201if (i<0)202 {203 i = i + MAXSIZE;204 }205 }206 }207return i;208break;209default:210break;211 }212213 };214215/*216Node* HashTable::solve3(int hashVal, int flag)//拉链法解决冲突217218{219 int i = hashVal; //第i条链220221 Node*p = ht[i]; //该链上的头指针222 while (p!=NULL)223 p = p->next;//往后遍历直到找到⼀个空节点⽤于存放user 224 return p;225};226227void HashTable::searchByNode(int flag, string at)//调⽤拉链法搜索228{229 int i = hash1(at,1);230 Node** ht = new Node*[maxSize]; //存放节点的⼀维数组231 Node*p = ht[i]; //该链上的头指针232 while (p!=NULL&&p->!=at)233 {234 p = p->next;235 }236};237*/238 User HashTable::input()239 {240 User user;241 cout << "请输⼊姓名:" << endl;242 cin >> ;243 cout << "请输⼊电话号码:" << endl;244 cin >> user.tel;245 cout << "请输⼊地址:" << endl;246 cin >> user.address;247return user;248 };249250void HashTable::creat(int flag)251 {252switch (flag)253 {254case1: //按姓名哈希创建哈希表255for (int i = 0; i < length; i++)256 {257 User newUser = input();258int val = hash1(,1);259if (tag[val] == 1)260 val = solve1(val,1);//线性探测法解决冲突261 E[val] = newUser;262 tag[val] = 1;263 }264break;265case2: //按电话号码哈希创建哈希表266for (int i = 0; i < length; i++)267 {268 User newUser = input();269int val = hash1(newUser.tel,2);270if(tag2[val] == 1)271 val = solve1(val,2);//线性探测法解决冲突272 E2[val] = newUser;273 tag2[val] = 1;274 }275break;276 }277 };278void HashTable::show(int flag)279 {280switch (flag)281 {282case1:283for (int i = 0; i < MAXSIZE; i++)284 {285if (tag[i] == 1)286 cout << E[i].name << "" << E[i].tel << "" << E[i].address << " 位于: " << i << endl; 287 }288break;289case2:290for (int i = 0; i < MAXSIZE; i++)291 {292if (tag2[i] == 1)293 cout << E2[i].name << "" << E2[i].tel << "" << E2[i].address << " 位于: " << i << endl; 294 }295break;296 }297298 };299300void HashTable::search(int flag,string at) //at表⽰索引内容301 {302int i = 0;303switch (flag)304 {305case1: //调⽤线性探测法查找姓名306 i = hash1(at,1);307if (tag[i] == 1 && E[i].name != at)308 i = solve1(i, 2);309if (i < 0 || tag2[i] == 0)310 {311 cout << "查⽆此⼈!" << endl;312return;313 }314if (tag[i] == 1 && E[i].name == at)315 cout << E2[i].name << "" << E2[i].tel << "" << E2[i].address << endl;316break;317case2: //调⽤⼆次探测法查找电话号码318 i = hash2(at);319if (tag2[i] == 1&&E2[i].tel!=at)320 i = solve2(i,2);321if (i < 0||tag2[i]==0)322 {323 cout << "查⽆此⼈!" << endl;324return;325 }326if (tag2[i] == 1 && E2[i].tel==at)327 cout << E2[i].name << "" << E2[i].tel << "" << E2[i].address << endl;328break;329 }330 };331332void HashTable::insert(int flag, User newUser){333int i = -1;334switch (flag)335 {336case1:337 i = hash1(,1);338if (tag[i] == 1||E[i]==newUser)339 i = solve1(i, 1);340if (i < 0)341 {342 cout << "表满!插⼊失败!" << endl;343return;344 }345if (tag[i] == 0)346 {347 E[i] = newUser;348 tag[i] = 1;349 length++;350 cout << "插⼊成功" << endl;351 }352case2:353 i = hash1(newUser.tel,2);354if (tag2[i] == 1 || E2[i] == newUser)355 i = solve1(i, 2);356if (i < 0)357 {358 cout << "表满!插⼊失败!" << endl;359return;360 }361if (tag2[i] == 0)362 {363 E2[i] = newUser;364 tag2[i] = 1;365 length++;366 cout << "插⼊成功" << endl;367 }368default:369break;370 }371 };372373void HashTable::del(int flag, string by) //by表⽰按照何种标签进⾏删除374 {375int i = -1;376int select;//选择是否删除377switch (flag)378 {379case1: //调⽤线性探测法查找姓名380 i = hash1(by,1);381if (tag[i] == 1 && E[i].name != by)382 i = solve1(i, 2);383if (i < 0 || tag2[i] == 0)384 {385 cout << "查⽆此⼈!" << endl;386return;387 }388if (tag[i] == 1 && E[i].name == by)389 {390 cout << E2[i].name << "" << E2[i].tel << "" << E2[i].address << endl; 391 cout << "是否删除 0.删了 1.算了" << endl;392 cin >> select;393if (select == 0)394 tag[i] = 0;//伪删除395 }396break;397case2: //调⽤⼆次探测法查找电话号码398 i = hash2(by);399if (tag2[i] == 1 && E2[i].tel != by)400 i = solve2(i, 2);401if (i < 0 || tag2[i] == 0)402 {403 cout << "查⽆此⼈!" << endl;404return;405 }406if (tag2[i] == 1 && E2[i].tel == by)407 {408 cout << E2[i].name << "" << E2[i].tel << "" << E2[i].address << endl; 409 cout << "是否删除 0.删了 1.算了" << endl;410 cin >> select;411if (select == 0)412 tag2[i] = 0;//伪删除413 }414break;415 }416 };417418void HashTable::save(int flag)419 {420 fstream out1("电话薄(姓名散列).txt", ios::out);421 fstream out2("电话薄(号码散列).txt", ios::out);422switch (flag)423 {424case1:425for (int i = 0; i < maxSize; i++)426 {427if (tag[i] == 1)428 out1 << E[i].name << "" << E[i].tel << "" << E[i].address << endl; 429 }430 cout << "已存⾄电话薄(姓名散列).txt" << endl;431return;432break;433case2:434for (int i = 0; i < maxSize; i++)435 {436if (tag2[i] == 1)437 out2 << E2[i].name << "" << E2[i].tel << "" << E2[i].address << endl; 438 }439 cout << "已存⾄电话薄(号码散列).txt" << endl;440return;441break;442default:443break;444 }445446 };hashtable.h1 #include <iostream>2 #include <string>3 #include <fstream>4 #include "hashtable.h"5using namespace std;67//菜单8void menu()9 {10 cout << " ****************************" << endl;11 cout << "|| 0.建表 ||" << endl;12 cout << "|| 1.查看 ||" << endl;13 cout << "|| 2.搜索 ||" << endl;14 cout << "|| 3.添加 ||" << endl;15 cout << "|| 4.删除 ||" << endl;16 cout << "|| 5.保存 ||" << endl;17 cout << "|| 6.退出 ||" << endl;18 cout << " ****************************" << endl;1920 }2122int main()23 {24 User user;25int size;//第⼀次创建的数据量⼤⼩26int select;//主菜单选项27int select_;//⼦菜单选项28 cout << "欢迎使⽤电话簿" << endl;29 HashTable ht;30while (1)31 {32 menu();33 cin >> select;34switch (select)35 {36case0:37 cout << "第⼀次使⽤,请输⼊要新建的电话本⼤⼩:" << endl;38 cin >> size;39 ht.length = size;40 cout << "1.姓名散列 2.电话号码散列" << endl;41 cin >> select_;42 ht.creat(select_);43break;44case1:45 cout << "1.姓名散列 2.电话号码散列" << endl;46 cin >> select_;47 ht.show(select_);48break;49case2:50 cout << "1.按姓名查找 2.按电话号码查找" << endl;51 cin >> select_;52if (select_==1)53 {54 cout << "输⼊姓名" << endl;55string name;56 cin >> name;57 ht.search(1, name);58 }59else if (select_ == 2)60 {61 cout << "输⼊号码" << endl;62string tel;63 cin >> tel;64 ht.search(2, tel);65 }66else67 cout << "不合法操作" << endl;68break;69case3:70 user = ht.input();71 cout << "1.插⼊到姓名散列表 2.插⼊到电话号码散列" << endl;72 cin >> select_;73 ht.insert(select_,user);74break;75case4:76 cout << "1.根据姓名删除 2.根据电话号码删除" << endl;77 cin >> select_;78if (select_ == 1)79 {80 cout << "输⼊姓名" << endl;81string name;82 cin >> name;83 ht.del(1, name);84 }85else if (select_ == 2)86 {87 cout << "输⼊号码" << endl;88string tel;89 cin >> tel;90 ht.del(2, tel);91 }92else93 cout << "不合法操作" << endl;94break;95case5:96 cout << "1.保存姓名散列表到本地 2.保存电话号码散列表到本地" << endl;97 cin >> select_;98 ht.save(select_);99case6:100return0;101 }102 }103 }main.cpp通过这次课程设计,总结如下1. C++技艺不精,语法不熟悉,⽐如模版类与运算符重载,指针更是不⼤熟练。

2015实验报告模板

2015实验报告模板

实验报告模板填写说明1、出现的红色部分请填写,并将红色文字删除2、算法描述是以老师建议的算法简要描述的,如果和你的实现方案或者细节不一致的,请自行修改描述。

3、在实验结果中粘贴真实测试结果截图,不必是100分,这个不作为最终实验评分依据,如:贵州大学计算机科学与技术学院计算机科学与技术系上机实验报告贵州大学计算机科学与技术学院计算机科学与技术系上机实验报告课程名称:数据结构班级:计科132实验日期:4月6日姓名:姓名学号:XXX指导教师:程欣宇实验序号:二实验成绩:一、实验名称栈与其应用二、实验目的与要求1、熟悉栈的原理和实现方式;2、掌握利用栈解决列车调度问题三、实验环境任何一种C++编写调试工具 + 清华数据结构Online Judge四、实验内容完成PA02的列车调度这道题五、算法描述与实验步骤列车调度问题是求解一个已知的顺序序列A,是否能够通过一个容量最大为m的栈S,调度为希望的序列B,如图:算法框架如下:贵州大学计算机科学与技术学院计算机科学与技术系上机实验报告贵州大学计算机科学与技术学院计算机科学与技术系上机实验报告贵州大学计算机科学与技术学院计算机科学与技术系上机实验报告贵州大学计算机科学与技术学院计算机科学与技术系上机实验报告贵州大学计算机科学与技术学院计算机科学与技术系上机实验报告3、从小顶堆中取出最小元素后,可以在log(n)的时间内恢复为小顶堆。

4、任意一个元素,可以在log(n)的时间内插入小顶堆。

最小堆物理结构最小堆逻辑结构在本题中,队列元素出队后,还会再入队,我们可以得出算法流程大致如下:初始化有些队列PQ,队列元素为字符串与其优先级读入参数n,m循环n次,读取每个元素,插入队列PQ,花费O(nlogn)建堆循环m次每次输出堆顶元素e将e乘以2以后再次入队实验步骤1、阅读PA04的任务调度这道题;2、采用小顶堆实现优先队列,建议实现为模板类;贵州大学计算机科学与技术学院计算机科学与技术系上机实验报告。

(完整版)设计散列表实现通讯录查找系统

(完整版)设计散列表实现通讯录查找系统

设计散列表实现通讯录查找系统#include<stdio.h>#include<stdlib.h>#include<string>#include <windows.h>#define MAXSIZE 20 //电话薄记录数量#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;否则返回UNSUCCESS if(strcmp(x,y)==0)return SUCCESS;else return UNSUCCESS;}Status NUM_BER; //记录的个数void getin(Record* a){//键盘输入各人的信息printf("输入要添加的个数:\n");scanf("%d",&NUM_BER);for(i=0;i<NUM_BER;i++){printf("请输入第%d个记录的用户名:\n",i+1);scanf("%s",a[i].name);printf("请输入%d个记录的电话号码:\n",i+1);scanf("%s",a[i].tel);printf("请输入第%d个记录的地址:\n",i+1);scanf("%s",a[i].add); //gets(str2);??????}}void ShowInformation(Record* a)//显示输入的用户信息{int i;for( i=0;i<NUM_BER;i++)printf("\n第%d个用户信息:\n 姓名:%s\n 电话号码:%s\n 联系地址:% s\n",i+1,a[i].name,a[i].tel,a[i].add);}void Cls(Record* a){printf("*");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++;printf("\nsum====================%d",sum);return sum;}int Hash1(NA str){//哈希函数int m;n=fold(str);//先将用户名进行折叠处理m=n%HASHSIZE; //折叠处理后的数,用除留余数法构造哈希函数return m; //并返回模值}int Hash2(NA str){//哈希函数long n;int m;n = atoi(str);//把字符串转换成整型数.m=n%HAreturn 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){printf("第%d记录无法解决冲突",i+1);//需要显示冲突次数时输出continue;}//无法解决冲突,跳入下一循环}H->elem[pp]=&(a[i]); //求得哈希地址,将信息存入H->count++;printf("第%d个记录冲突次数为%d。

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

实验课题:做这个实验时采用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 );}。

相关文档
最新文档