通讯录链表的实现sunxu.docx
《通讯录链表的实现sunxu.docx》由会员分享,可在线阅读,更多相关《通讯录链表的实现sunxu.docx(21页珍藏版)》请在冰豆网上搜索。
通讯录链表的实现sunxu
实验课程名称数据结构课程设计
专业班级
学生姓名
学号
指导教师
2012至2013学年第1学期第一至二周
目录
第一章概述2
本课程设计的目的3
开发的意义3
开发环境及实现技术4
第二章系统分析5
第三章概要设计6
第四章详细设计8
1.建立通讯录链表的设计8
2.通信者信息的插入9
3.在有序链表中查找指定结点10
4.通讯者记录的删除12
5.通讯录链表的输出12
第五章运行与测试13
1.通讯录链表的建立13
2.通讯录结点的插入14
3.通讯录结点的查询14
4.通讯录结点的删除15
5.通讯录链表的输出16
6.退出管理系统16
第六章实验心得16
附录(实验源代码)17
参考文献22
第一章概述
本课程设计的目的
本课程设计可加深对课堂理论学习的理解,增强动手能力,以培养学生合作的能力,为毕业设计作好实践环节上的准备。
通讯录系统是在学校常见的计算机信息管理系统。
它的主要任务是对个人信息进行管理,如学生信息的输入、查询、修改、增加、删除,迅速准确地完成各种学生信息的统计和查询。
通讯录管理系统是每一个用户管理通讯录的不可缺少的一个管理信息系统,它的内容对于用户的管理者来说是至关重要的,所以通讯录管理系统应该能够为每一个用户的管理者提供充足的信息和快捷的查询手段大大的方便用户合理的管理通讯录。
随着科学技术的不断提高,计算机科学日渐成熟,网上通讯工具的迅速发展其强大的功能已为人们深刻认识,它已进入人类社会的各个领域并发挥着越来越重要的作用。
作为计算机应用的一部分,使用计算机对通讯录进行管理,具有着手工管理所无法比拟的优点如:
检索迅速、查找方便、可靠性高、存储量大、保密性好、寿命长、成本低等。
这些优点能够极大地提高通讯录管理的效率,也是用户理财的科学化、正规化管理,与先进科学技术接轨的重要条件。
因此开发这样一套管理软件成为很有必要的事情对于我们即将计算机专业毕业的学员来说也是一次将计算机应用于现实管理的一次很有意义的实践活动。
开发的意义
计算机已经成为我们学习和工作的得力助手使用其可方便的管理通讯录今天计算机的价格已经十分低廉性能却有了长足的进步。
它已经被应用于许多领域。
现在我国的通讯录管理水平还停留在纸介质的基础上这样的机制已经不能适应时代的发展因为它浪费了许多人力和物力在信息时代这种传统的管理方法必然被计算机为基础的信息管理所取代。
我作为一个计算机应用专业的毕业生希望可以在这方面有所贡献。
改革的总设计师邓小平同志说过“科学技术是第一生产力”我希望能用我所学的知识编制出一个实用的程序来帮助用户进行财务管理。
开发这一系统的好处大约有以下几点:
第一、可以存储大量的通讯录信息安全、高效
第二、只需一档案录入员即可操作系统节省人力
第三、可以迅速查到所需通讯录信息。
为将来用户上网做好准备跟据2003年中国电信的调查报告显示我国的上网人数已达到1870万互联网已经十分普及况且现在网上通讯已经出现本系统为用户将来的上网作了先期工作。
开发环境及实现技术
开发环境硬件系统奔腾100以上CPU、64M以上内存、1G以上硬盘、光驱。
软件系统Windows9x或更高版本、VisualBasic6.0中文版。
微软公司的VisualBasic6.0是Windows应用程序开发工具使目前最为广泛的、易学易用的面向对象的开发工具。
VisualBasic提供了大量的控件这些控件可用于设计界面和实现各种功能减少了编程人员的工作量也简化了界面设计过程从而有效的提高了应用程序的运行效率和可靠性。
本系统有分6个功能:
(1)通讯录链表的建立
(2)通讯录结点的插入(3)通讯录结点的删除(4)通讯录结点的查询(5)通讯录链表的输出(6)退出管理系统。
其主要利用结构类型,指针,数组,函数等C语言知识来实现
第二章系统分析
该通讯录主要分为六个模块:
1)新建2)插入3)查询4)删除5)输出6)退出。
在开始菜单中对应的功能数字是0-5。
可以按照自己想要操作的动作选择对应的数字实现相应的功能。
对于插入主要是按学号的升序来插入通讯者的信息。
在查找中分为四个查找方式:
1)按学号查询2)按姓名查询3)按号码查询4)按地址查询。
在删除中由于学号是主关键字,是唯一的,所以删除按学号来删除会比较方便。
而输出是按一个指针p指向头指针haed,按循环来输出直到p=NULL则结束输出。
技术难点分析主要内容:
本课题在设计过程中所遇到的技术难点及解决方法。
在本次试验中我觉得我遇见了一些技术上的难点,刚开始是通讯录的建立,要用到数据结构中的知识,主要要用到链表和结构体。
在通讯录的插入的时候主要是用到学号的升值法插入,在此过程中要申请结点m和n,而且将要插入结点p插在两结点之间。
在通讯录的查询当中主要分为四类:
1).按学号查找的函数;2).按姓名查找的函数;3).按电话查找的函数;4).按住址查找的函数。
其实原理一样,只是使用strcmp()函数匹配出和要查找的通讯者信息相同的结点,并且将其所有的信息输出。
在删除函数我开始觉得删除的时候很困难,后来我是按学号删除的,因为学号是关键字,主要注意在删除后对一些结点需要改变p=p->next;p->next=p->next->next;free(q);如果没找到则q=q->next。
第三章概要设计
各模块功能的分析:
(1)主函数:
可让用户选择用系统的哪个功能,从而去连接到相应的子函数;
(2)写入数据:
让用户输入通讯录里的内容,并将内容保存好;
(3)读取数据:
显示通讯录里已保存的数据;
(4)追加数据:
让用户在通讯录原有数据中,再加上新的数据;
(5)查找数据:
通过用户输入需要找的名字来找到相关资料;
(6)删除数据:
让用户删除想要删除的资料;
总体框架:
结构框图:
变量名
数据类型
中文释义
num
int
编号
name
char
姓名
sex
char
性别
phone
int
电话
addr
char
地址
主函数框图
主函数设计要求简洁,只提供部分提示语和函数的调用
【程序】
第四章详细设计
1.建立通讯录链表的设计
要建立链表,首先要生成结点,因此,尾插法建立链表,算法描述如下:
(1)使链表的头尾指针head、real指向新生成的头结点(也是尾结点);
(2)置结束标志为0(假);
(3)while(结束标志不为真)
{
P指向新生成的结点;
读入一个通讯者数据至新结点的数据域;
将新结点链到尾结点之后;
使尾指针指向新结点;
提示:
是否结束建表,读入一个结束标志;
}
(4)尾结点指针域置空值NULL.
具体算法实现如下:
/******************************/
/*用尾插法建立通讯录链表函数*/
/*****************************/
linklistcreatelist(void)
{//尾插法建立带头结点通讯录链表算法
linklisthead=(listnode*)malloc(sizeof(listnode));
listnode*p,*rear;
intflag=0;//结束标志置0
rear=head;//尾指针初始指向头结点
while(flag==0)
{p=(listnode*)malloc(sizeof(listnode));//申请新结点
printf("编号(4)姓名(8)性别电话(11)地址(31)\n");
printf("----------------------------------------------------------------\n");
scanf("%s%s%s%s%s",p->data.num,p->data.name,p->data.sex,p->data.phone,p->data.addr);
rear->next=p;//新结点连接到尾结点之后
rear=p;//尾指针指向新结点
printf("结束建表吗?
(1/0):
");
scanf("%d",&flag);//读入一个标志数据
}
rear->next=NULL;//终端结点指针域置空
returnhead;//返回链表头指针
}
2.通信者信息的插入
链表结点的插入,是要求将一个通讯者数据结点按其编号的次序插入有序通讯录表的相应位置,以保持通讯录表的有序性,插入结点的基本思想是:
使用两个指针变量p1和p2分别指向当前刚访问过的结点和下一个待访问的结点,循环顺序查找链表,寻找插入结点的位置,其中p1指向待插入位置的前一个结点。
算法描述如下:
(1)用p1指向原链表头结点,p2指向链表的第一个结点;
(2)While(p2!
=NULL&&p2->data.numdata.num)
{
p1=p2;//p1指向刚访问过的结点;
p2=p2->next;//p2指向表的下一个结点;
}
(3)插入新结点。
具体实现如下:
/********************************/
/*在有序链表head中插入结点*/
/********************************/
voidInsertNode(LinkListhead,ListNode*p)
{
ListNode*p1,*p2;
p1=head;
p2=p1->next;
while(p2!
=NULL&&strcmp(p2->data.num,p->data.num)<0)
{
p1=p2;//p1指向刚访问过的结点
p2=p2->next;//p2指向表的下一个结点
}
p1->next=p;//插入p所指向的结点
p->next=p2;//连接表中剩余部分
}
3.在有序链表中查找指定结点
在有序表中查找指定结点的算法是比较简单的,其基本思路是:
首先输入要查找的通讯者的编号或姓名,从表头顺序访问表中结点。
成功返回一个指向查找到的通讯者信息的结点;若失败,则返回一个空指针值NULL.
当按编号查找时,如果需要查找的通讯者编号不在表中,则不一定需要循环比较到表尾,因表是按编号递增有序的;按姓名查找时,则要循环比较到表尾,才能确定查不到的情况。
因此,查找算法实现如下:
/********************************/
/*通讯录链表上的查找*/
/********************************/
listnode*listfind(linklisthead)
{
listnode*p;
charnum[5];
charname[9];
intxz;
printf("=====================\n");
printf("1.按编号查询\n");
printf("2.按姓名查询\n");
printf("=====================\n");
printf("请选择:
");
p=head->next;//假定通讯录表带头结点
scanf("%d",&xz);
if(xz==1){
printf("请输入要查找者的编号:
");
scanf("%s",num);
while(p&&strcmp(p->data.num,num)<0)
p=p->next;
if(p==NULL||strcmp(p->data.num,num)>0)
p=NULL;//没有查到要查找的通讯者
}
else
if(xz==2){
printf("请输入要查找者的姓名:
");
scanf("%s",name);
while(p&&strcmp(p->data.name,name)!
=0)
p=p->next;
}
returnp;
}
4.通讯者记录的删除
链表上结点的删除是比较简单的,先调用查询函数,查询到要删除的结点,删除结点即可。
其算法如下:
/********************************/
/*通讯录链表上结点的删除*/
/********************************/
voidDelNode(LinkListhead)
{
charjx;
ListNode*p,*q;
p=ListFind(head);//调用查找函数
if(p==NULL)
{
printf("没有查到要删除的通讯者!
\n");
return;
}
printf("真的要删除该结点吗?
(y/n):
\n");
scanf("%c",&jx);
if(jx=='y'||jx=='Y'){
q=head;
while(q!
=NULL&&q->next!
=p)
q=q->next;
q->next=p->next;//删除结点
free(p);//释放被删除的结点空间
printf("通迅者已被删除!
\n");
}
5.通讯录链表的输出
通讯录链表的输出相对来说比较简单,只要将表头指针赋给一个指针变量p,然后用p向后扫描,直至表尾,p为空为止。
因此,其输出链表算法如下:
/********************************/
/*通讯录链表上结点的删除*/
/********************************/
voidprintlist(linklisthead)
{
listnode*p;
p=head->next;//因为链表带头接点,使P指向链表开始结点
printf("编号姓名姓别联系电话地址\n");
printf("-----------------------------------------------------------------------\n");
while(p!
=NULL)
{
printf("%s,%s,%s,%s,%s\n",p->data.num,p->data.name,p->data.sex,p->data.phone,p->data.addr);
printf("-------------------------------------------------------\n");
p=p->next;
}
}
第五章运行与测试
1.通讯录链表的建立
2.通讯录结点的插入
3.通讯录结点的查询
4.通讯录结点的删除
5.通讯录链表的输出
6.退出管理系统
第六章实验心得
这是上大学以来第一次自主完成这种实验报告,看起来很简单,做起来感觉很吃力,尤其是对这个实验程序的调试。
会出现很多错误,但是经过老师的指导,和同学们的讨论终于完成了这次实验,同时感觉自己学到了很多东西。
对于这种大程序的把握也越来越熟络了。
本实验是制作通讯录链表,要分多种函数,实现通讯录的建立,插入,查询,删除以及退出。
用到了尾插法,以及指针域的实现,总之这次实验让我受益匪浅,感慨良多。
附录(实验源代码)
/******************************/
/*主控菜单处理测试程序main2.c*/
/*****************************/
#include
#include
#include
typedefstruct{//通讯录结点类型
charnum[5];//编号
charname[9];//姓名
charsex[3];//性别
charphone[13];//电话
charaddr[31];//地址
}datatype;
typedefstructnode{//结点类型定义
datatypedata;//结点数据域
structnode*next;//结点指针域
}listnode;
typedeflistnode*linklist;
linklisthead;
listnode*p;
//函数说明
intmenu_select();
linklistcreatelist(void);
voidinsertnode(linklisthead,listnode*p);
listnode*listfind(linklisthead);
voiddelnode(linklisthead);
voidprintlist(linklisthead);
//主函数
voidmain()
{
for(;;){
switch(menu_select())
{
case1:
printf("***************************\n");
printf("*通讯录链表的建立*\n");
printf("****************************\n");
head=createlist();
break;
case2:
printf("***************************\n");
printf("*通讯者信息的添加*\n");
printf("******************************************\n");
printf("编号(4)姓名(8)性别电话(11)地址(31)\n");
printf("*******************************************\n");
p=(listnode*)malloc(sizeof(listnode));
scanf("%s%s%s%s%s",p->data.num,p->data.name,p->data.sex,p->data.phone,p->data.addr);
insertnode(head,p);
break;
case3:
printf("*************************************\n");
printf("*通讯录信息的查询*\n");
printf("***************************************\n");
p=listfind(head);
if(p!
=NULL){
printf("编号姓名性别联系电话地址\n");
printf("----------------------------------------------------------------------------------\n");
printf("%s,%s,%s,%s,%s\n",p->data.num,p->data.name,p->data.sex,p->data.phone,p->data.addr);
printf("----------------------------------------------------------------------------------\n");
}
else
printf("没查到要查询的通讯者!
\n");
break;
case4:
printf("************************************\n");
printf("*通讯录信息的删除*\n");
printf("*************************************\n");
delnode(head);
break;
case5:
printf("************************************\n");
printf("*通讯录链表的输出*\n");
printf("*************************************\n");
printlist(head);
break;
case0:
printf("\t再见!
\n");
return;
}
}
}
/*********************/
/*菜单选择函数程序*/
/*******************/
intmenu_select()
{
intsn;
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("请选择0-5:
");
for(;;)
{
scanf("%d",&sn);
if(sn<0||sn>5)
printf("\n\t输入错误,重选0-5:
");
else
break;
}
returnsn;
}
/******************************/
/*用尾插法建立通讯录链表函数*/
/*****************************/
linklistcreatelist(void)
{//尾插法建立带头结点通讯录链表算法
linklisthead=(listnode*)malloc(sizeof(listnode));
listnode*p,*rear;
intflag=0;//结束标志置0
rear=head;//尾指针初始指向头结点
while(flag==0)
{p=(listnode*)malloc(sizeof(listnode));//申请新结点
printf("编号(4)姓名(8)性别电话(11)地址(31)\n");
printf("----------------------------------------------------------------\n");
scanf("%s%s%s%s%s",p->da