云南大学软件学院数据结构实验学生信息管理系统

发布时间:2020-06-07 06:09:07   来源:文档文库   
字号:

word/media/image1.gif

(本实验项目方案受“教育部人才培养模式创新实验区X3108005”项目资助)

实验难度: A □ B □ C □

学  期:  2013秋季学期

任课教师:    张德海   

实验题目: 学生信息管理系统

小 组 长:

联系电话:

电子邮件:

完成提交时间:2013年 12月17日

《数据结构实验》成绩考核表

综合得分:(满分100分)

指导教师:

综合得分:(满分100分)

指导教师:

综合得分:(满分100分)

指导教师:

一、【实验构思(Conceive)】(10%)

设计主要要求分别以电话号码和用户名为关键字建立哈希表,并实现查找功能。所以本设计的核心问题是如何解决散列的问题,由于结点的个数无法确认,并且如果采用线性探测法散列算法,删除结点会引起“信息丢失”的问题。所以采用链地址法散列算法。采用链地址法,当出现同义词冲突时,使用链表结构把同义词链接在一起。 首先,解决的是定义链表结点,在链接地址法中,每个结点对应一个链表结点,它由三个域组成,而由于该程序需要分别用电话号码和用户名为关键字建立哈希表,所以该链表结点它是由四个域组成。name[8] 、num[11]和address[20]都是char浮点型采用链地址法,其中的所有同义词构成一个单链表,再由一个表头结点指向这个单链表的第一个结点。这些表头结点组成一个一维数组,即哈希表。

二、【实验设计(Design)】(20%)

设计哈希表实现学生信息管理系统完成以下要求:

(1)设每个记录有下列数据项:电话号码、用户名、地址;

(2)从键盘输入各记录,分别以电话号码和用户名为关键字建立哈希表;

(3)采用再哈希法解决冲突;

(4)查找并显示给定电话号码的记录;

(5)查找并显示给定用户的记录。

具体思路为:

(1)对于以号码为关键字的散列函数,是将十一个数字全部相加,然后对20求余。

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

(2)要添加用户信息,即要有实现添加结点的功能函数,所以要设计一个必须包括

一个输入结点信息、添加结点的函数;

(3)要实现查找函数,则必须包括一个查找结点的函数;

另外还有一个必不可少的就是运行之后要有一个主菜单,即要设计一个主函数

(4)最后,程序完成后要对程序进行编译调试,执行后要选择数据进行测试,

三、【实现描述(Implement)】(30%)

1 建立节点

struct node

{

char name[8],address[20];

char num[11];

node * next;

};

typedef node* pnode; //可以为一个已有的数据类型声明多个别名

typedef node* mingzi;

node **phone;

node **nam;

node *a;

2 哈希函数的定义 本程序要设计两个

hash()函数,分别对应电话号码和用户名。对关键字进行模运算,

将运算结果所得的余数作为关键字(或结点)的存储地址,方法如下:以电话号码为关键字建立哈希函数hash(char num[11])。以用户名为关键字建立哈希函数hash2(char name[8])。利用强制类型转换,将用户名的每一个字母的ASCLL码值相加并且除以20后的余数。将计算出来的数作为该结点的地址赋给key2。

void hash(char num[11]); //以电话号码为关键字建立哈希函数

//哈希函数的主旨是将电话号码的十一位数字全部加起来

{

int i = 3;

key=(int)num[2];

while(num[i]!=NULL)

{

key+=(int)num[i];

i++;

}

key=key%20; } //利用强制类型转换,将用户名的每一个字母的ASCLL码值相加并且除

以20后的余数

void hash2(char name[8]); //哈希函数 以用户名为关键字建立哈希函数

{

int i = 1;

key2=(int)name[0];

while(name[i]!=NULL)

{

key2+=(int)name[i];

i++;

}

key2=key2%20;

}

3 哈希查找

想要实现查找功能,同样需要两个查找函数,无论以用户名还是以电话号码为关键字,首先,都需要利用hash函数来计算出地址。再通过比对,如果是以电话号码为关键字,比较其电话号码是否相同,如果相同则输出该结点的所有信息,如果以用户名为关键字,则比较用户名是否相同,如果相同则输出该结点的所有信息。如果找不到与之对应相同的,则输出“无此记录”。 void find(char num[11]) ; //

在以电话号码为关键字的哈希表中查找用户信息

4 流程图

以学号为关键字的hash函数流程图

以姓名为关键字的hash函数流程图

四、【测试结果(Testing)】(10%)

1、添加记录

2、查找记录

3、姓名散列

4、学号散列

5、清空记录

五、【实验总结】(10%)

卢晨阳 20121120205:

主要负责:程序算法的设计和程序实现,实验报告的部分撰写

经验总结:1、我们定义了两个哈希函数,一个以学号为关键字,另一个以姓名ASCII之和求模之后的值为关键字。第一种是将学号从第二位开始逐一累加并将所得结果对30求模得哈希地址。第二种则是将姓名字符进行强制类型转换之后得ASCII码相加对30求模得哈希地址。

2、哈希表问题,在存储位置和关键字之间建立对应关系f,根据对应关系f找到定值K。若结构中存在关键字和定值K相等的记录,必定在f(K)的存储位置上,由此可以省去比较过程,直接找到所查记录。

3、。由于长度无法确定,并且如果采用线性探测法散列算法,删除结点会引起“信息丢失”的问题,所以采用链地址法散列算法。采用链地址法,当出现同义词冲突时,可以使用链表结构把同义词链接在一起 即同义词的存储地址不是散列表中其他的空地址。

毛钰源 20121120036:

主要负责:程序算法的部分改进和界面设计,部分接口的实现

经验总结:1、哈希表的实现,其主要的精妙之处在于,重载了[]这个运算符,然后在判断哈希表是否为空时,初始化。

2、在实验中虽然使用得仍然是倒插入指针头的方法,但其始终保持着在散列的地址第一位。且在此次实验中,主要是要分清nHash与key二者的区别,前者是由后者通过HashKey()函数算出来的,但还是有一定的区别的。。

3、哈希表其实不难,考验的是我们的学习态度,独立思考问题,和解决问题的能力。把握这次机会大有收获。

刘羽 20121120274:

主要负责:程序部分算法的实现,数据测试和部分实验报告的撰写

经验总结:1、在程序的重载的[]函数里,通过GetAssocAt()函数来判断KEY是滞相等,如果不等,则新关联一个到当前的哈希表内。否则,返回当前值。

2、我们定义有3个域的节点,这三个域分别为学号char num[30],姓名char name[30],地址char address[30]。这种类型的每个节点对应链表中的每个节点,其中电话号码和姓名可分别作关键字实现哈希表的创建。

3、“哈希表问题”基本算法老师在课堂上有涉及过,但具体的还要靠自己去钻研。通过本次课程设计对哈希表问题有了一个比较全面的认识和了解。

六、【项目运作描述(Operate)】(10%)

在运作部分没有图形界面,只能在DOS下面运行,虽然成本很低,但推广的价值意义不是很大。且此次程序仍然能够满足一些要求,比如哈希表的建立以及解决冲突问题,程序中查找也可以正常实现,是基本达到了实验的要求。

七、【代码】(10%)

#include

#include

#define NULL 0

unsignedint key;

unsignedint key2;

int *p;

struct node

{

char name[8],address[20];

char num[11];

node * next;

};

typedef node* pnode;

typedef node* mingzi;

node **phone;

node **nam;

node *a;

void hash(char num[11])

{

int i = 3;

key=(int)num[2];

while(num[i]!=NULL)

{

key+=(int)num[i];

i++;

}

key=key%20;

}

void hash2(char name[8])

{

int i = 1;

key2=(int)name[0];

while(name[i]!=NULL)

{

key2+=(int)name[i];

i++;

}

key2=key2%20;

printf("\ndz====================%d\n",key2);

}

node* input()

{

node *temp;

temp = new node;

temp->next=NULL;

printf("请输入姓名:");

scanf("%s",temp->name);

printf("输入地址:");

scanf("%s",temp->address);

printf("输入学号:");

scanf("%s",temp->num);

return temp;

}

int apend()

{

node *newphone;

node *newname;

newphone=input();

newname=newphone;

newphone->next=NULL;

newname->next=NULL;

hash(newphone->num);

hash2(newname->name);

newphone->next = phone[key]->next;

phone[key]->next=newphone;

newname->next = nam[key2]->next;

nam[key2]->next=newname;

return 0;

}

void create()

{

int i;

phone=new pnode[20];

for(i=0;i<20;i++)

{

phone[i]=new node;

phone[i]->next=NULL;

}

}

void create2()

{

int i;

nam=new mingzi[20];

for(i=0;i<20;i++)

{

nam[i]=new node;

nam[i]->next=NULL;

}

}

void list()

{

int i;

node *p;

for(i=0;i<20;i++)

{

p=phone[i]->next;

while(p)

{

printf("%s_%s_%s\n",p->name,p->address,p->num);

p=p->next;

}

}

}

void list2()

{

int i;

node *p;

for(i=0;i<20;i++)

{

p=nam[i]->next;

while(p)

{

printf("%s_%s_%s\n",p->name,p->address,p->num);

p=p->next;

}

}

}

void find(char num[11])

{

hash(num);

node *q=phone[key]->next;

while(q!= NULL)

{

if(strcmp(num,q->num)==0)

break;

q=q->next;

}

if(q)

printf("%s_%s_%s\n",q->name,q->address,q->num);

else printf("无此记录\n");

}

void find2(char name[8])

{

hash2(name);

node *q=nam[key2]->next;

while(q!= NULL)

{

if(strcmp(name,q->name)==0)

break;

q=q->next;

}

if(q)

printf("%s_%s_%s\n",q->name,q->address,q->num);

else printf("无此记录\n");

}

void menu() //菜单

{

printf("\t\t\t $$$$哈希表实验$$$$\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("\t\t\t 5.清空记录\n");

printf("\t\t\t 6.退出系统\n");

}

int main()

{

char num[11];

char name[8];

create();

create2() ;

int sel;

while(1)

{

menu();

scanf("%d",&sel);

if(sel==2)

{

printf("7学号查询,8姓名查询\n");

int b;

scanf("%d",&b);

if(b==7)

{

printf("请输入学号\n");

scanf("%s",num);

printf("输出查找的信息\n");

find(num);

}

else

{

printf("请输入姓名\n");

scanf("%s",name);

printf("输出查找的信息\n");

find2(name);

}

}

if(sel==3)

{

printf("姓名散列结果\n");

list2();

}

if(sel==1)

{

apend();

}

if(sel==4)

{

printf("学号散列结果\n");

list();

}

if(sel==5)

{

printf("列表已清空\n");

create();create2();

}

if(sel==6)

return 0;

}

return 0;

}

本文来源:https://www.2haoxitong.net/k/doc/d6c29b89f11dc281e53a580216fc700abb6852a2.html

《云南大学软件学院数据结构实验学生信息管理系统.doc》
将本文的Word文档下载到电脑,方便收藏和打印
推荐度:
点击下载文档

文档为doc格式