数据结构课程实践之通讯录程序报告.docx
- 文档编号:3502053
- 上传时间:2022-11-23
- 格式:DOCX
- 页数:16
- 大小:19.43KB
数据结构课程实践之通讯录程序报告.docx
《数据结构课程实践之通讯录程序报告.docx》由会员分享,可在线阅读,更多相关《数据结构课程实践之通讯录程序报告.docx(16页珍藏版)》请在冰豆网上搜索。
数据结构课程实践之通讯录程序报告
哈尔滨理工大学管理学院信息系
课程设计
(数据结构)
班级_信息11-2班
姓名
学号********
2013年6月30日
通讯录管理系统的设计与实现
第1章:
问题描述
通讯录管理系统一般包括通讯者结点信息的插入、查询、删除、更新以及通讯录信息的输出等功能。
而通讯者的信息一般包括编号、姓名、性别、电话以及地址等项。
现假设链表结点仅含有一个数据域和一个指针域。
数据域是为了描述通讯者的有关信息,定义一个通讯者的结点类型:
Typedefstruct{
Charnum[5];
Charname[9];
Charsex[3];
Charphone[13];
Charaddr[31];
}DataType;
因此,线性表的链式存储结构定义如下:
Typedefstructnode{
DataTypedata;
Structnode*next;
}ListNode*LinkList;
ListNode*p;
LinkListhead;
第2章.算法设计
2.1数据结构设计
管理信息系统的设计一般都采用自顶向下的设计方法,它是一种逐步求精的设计程序的过程和方法,即对要完成的任务进行分解,先对最高层次中的问题进行定义、设计、编程和测试,而将其中未解决的问题作为一个子任务放到下一层次中去解决,这样逐层、逐个的进行定义、设计、编程和测试,直到所有层次上的问题均由实用程序来解决,就能设计出具有层次结构的程序。
1.顶层主控菜单设计
(1)设计菜单内容
程序运行后,给出6个菜单项的内容和输入提示。
1.通讯录链表的建立
2.通讯者信息的插入
3.通讯者信息的查询
4.通讯者信息的修改
5.通讯者信息的删除
6.通讯者链表的输出
1.退出管理系统
请选择0-6:
(2)实现循环和功能选择
假设输入选择用变量sn存储,它作为menu_select函数的返回值提供给switch语句。
使用for循环实现重复选择,并在主函数main()中实现。
#include
#include
Voidmain()
{
For(;;){
Switch(menu_select())
{
Case1:
Printf(“通讯录链表的建立\n”);
Break;
Case2:
Printf(“通讯者信息的插入\n”);
Break;
Case3:
Printf(“通讯者信息的查询\n”);
Break;
Printf(“通讯者信息的修改\n”);
Break;
Case4:
Printf(“通讯者信息的修改\n”);
Break;
Case5:
Printf(“通讯者信息的删除\n”);
Break;
Case6:
Printf(“通讯录链表的输出\n”);
Break;
Case0:
Printf(“再见!
\n”);
Return;
}
}
}
(3)得到sn的合理值
如前所述,应该设计一个函数用来输出提示信息和处理输入,这个函数应该返回一个数值sn,以便供给switch语句使用。
假设函数名为menu_select,设计的参考程序如下:
Intmenu_select()
{
Intsn;
Printf(“通讯录管理系统\n”);
Printf(“===========================\n”);
Printf(“1.通讯录链表的建立\n”);
Printf(“2.通讯者信息的插入\n”);
Printf(“3.通讯者信息的查询\n”);
Printf(“4.通讯者信息的修改\n”);
Printf(“5.通讯者信息的删除\n”);
Printf(“6.通讯者信息的输出\n”);
Printf(“0.退出管理系统\n”);
Printf(“===========================\n”);
Printf(“请选择0-6”);
For(;;)
{
Scanf(“%d”,&sn);
If(sn<0||sn>6)
Printf(“\n\t输入错误,重选0-6”);
Else
Break;
}
Returnsn;
}
对于sn输入值,在switch中case语句对应数字1-6,对于不符合要求的输入,提示输入错误并要求重新输入。
2.2算法设计
功能模块函数设计
(1)通讯录链表的建立
这个实际上是要求建立一个带头结点的单链表。
这里介绍尾插法建立链表的算法设计思想及具体算法实现。
尾插法建立链表的算法描述如下:
1)使链表的头尾指针head.rear指向新生成的头结点(也是为结点)
2)至结束标志为0
3)设计循环语句
While(结束标志不为真)
{
循环语句;
}
4)尾结点指针域置空值NULL
(2)通讯者信息的插入
插入结点的基本思想是:
使用两个指针变量p1和p2分别向当前刚访问过的结点和下一个带访问的结点,循环顺序查找链表,寻找插入结点的位置,其中p1指向待插入位置的前一个结点。
插入操作时非常简单的。
其实现算法描述如下:
1)用p1指向原链表头结点,p2指向链表的第一个结点。
2)设计循环语句如下:
While(p2!
=NULL&&p2->data.num
{
P1=p2;
P2=p2->next;
}
3)插入新结点
(3)在有序链表中查找指定结点
基本思想是:
首先输入要查找的通讯者的编号或姓名,从表头顺序访问表中结点,若查找成功,则返回一个指向查找到的通讯者信息的结点,若查找失败,则返回一个空的指针值NULL.
(4)通讯者信息的修改
信息修改一般只需要修改通讯者的联系电话或通讯地址,因此,先查找到需要修改的通讯者,修改相应的数据项即可。
其算法如下:
VoidChangeNode(LinkListhead)
{
ListNode*p;
P=ListFind(head)
If(p!
=NULL){
Printf(“编号姓名性别电话地址\n”);
Printf(“-------------------------------------------\n”);
Printf(“%s,%s,%s,%s\n”,p->data.num,p->data.name,
p->data.sex,p->data.phone,p->data.addr);
printf(“------------------------------------------\n”);
printf(“输入该通讯者正确的联系电话通讯地址:
\n中间用空格分隔\n”);
}
Elseprintf(“没查到要查询的通讯者!
\n”);
Break;
}
(5)通讯者记录的删除
链表上结点的删除时比较简单的,即先调用查询函数,查询到要删除的结点,删除结点即可。
其算法如下:
VoidDelNode(LinkListhead)
{
LinkNode*p,*q;
P=ListFond(head);
If(p=NULL){
Printf(“没有查到要删除的通讯者\n”);
Return;
}
q=head;
while(q!
=null&&q->next!
=p)
q=q->next;
q->next=p->next;
free(p)
printf(“通讯者已被删除!
\n”);
}
(6)通讯录链表的输出
通讯录链表的输出相对来说比较简单,只要将表头指针赋给一个指针变量p,然后用p向后扫描,直至表尾,p为空为止。
其算法如下:
VoidprintList(LinkListhead)
{
ListNode*p;
P=head->next;
Printf(“编号姓名性别电话地址\n”);
Printf(“-------------------------------------------\n”);
While(p!
=NULL)
{
Printf(“%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;
}
}
完整的程序清单
#include
#include
#include
typedefstruct{
charnum[5];
charname[9];
charsex[3];
charphone[13];
charaddr[31];
}DataType;
typedefstructnode{
DataTypedata;
structnode*next;
}ListNode,*LinkList;
LinkListhead;
ListNode*p;
intmenu_select();
LinkListCreateList(void);
voidInsertNode(LinkListhead,ListNode*p);
ListNode*ListFind(LinkListhead);
voidDelNode(LinkListhead);
voidPrintList(LinkListhead);
voidChangeNode(LinkListhead);
voidmain()
{
for(;;){
switch(menu_select())
{
case1:
printf("**************************************\n");
printf("*通讯录链表的建立*\n");
printf("**************************************\n");
head=CreateList();
break;
case2:
printf("**************************************\n");
printf("*通信者信息的插入*\n");
printf("**************************************\n");
printf("请顺序输入编号、姓名、性别、电话和地址\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("-------------------------------------");
printf("%s%S%s%s%s\n",p->data.num,p->data.name,
p->data.sex,p->data.phone,p->data.addr);
printf("-------------------------------------");
}
else
printf("没查到要查询的通讯者!
\n");
break;
case4:
printf("**************************************\n");
printf("*通讯者信息的修改*\n");
printf("**************************************\n");
ChangeNode(head);
break;
case5:
printf("**************************************\n");
printf("*通讯者信息的删除*\n");
printf("**************************************\n");
DelNode(head);
break;
case6:
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("6.通讯录链表的输出\n");
printf("0.退出管理系统\n");
printf("=====================\n");
printf("请选择0-6:
");
for(;;)
{
scanf("%d",&sn);
if(sn<0||sn>6)
printf("\n\t输入错误,重选0-6:
");
else
break;
}
returnsn;
}
LinkListCreateList(void)
{
LinkListhead=(ListNode*)malloc(sizeof(ListNode));
ListNode*p,*rear;
charflag='y';
rear=head;
while(flag=='y')
{p=(ListNode*)malloc(sizeof(ListNode));
printf("请顺序输入编号、姓名、性别、电话和地址\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("继续输入么?
(y/n):
");
getchar();
scanf("%c",&flag);
}
rear->next=NULL;
returnhead;
}
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;
p2=p2->next;
}
p1->next=p;
p->next=p2;
}
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;
}
voidDelNode(LinkListhead)
{
charjx;
ListNode*p,*q;
p=ListFind(head);
if(p==NULL){
printf("没有查到要删除的通讯者!
\n");
return;
}
printf("真的要删除该结点吗?
(y/n):
");
getchar();
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");
}
}
voidPrintList(LinkListhead)
{
ListNode*p;
p=head->next;
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;
}
}
voidChangeNode(LinkListhead)
{
ListNode*p;
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");
printf("输入该通讯者正确的联系电话通讯地址:
\n中间用空格分隔\n");
scanf("%s%s",p->data.phone,p->data.addr);
}
else
printf("没查到要查找的通讯者!
\n");
}
第3章.运行与设计
运行结果如下:
通讯录管理系统
===================
1、通讯录链表的建立
2、通讯者信息的插入
3、通讯者信息的查询
4、通讯者信息的修改
5、通讯者信息的删除
6、通讯录链表的输出
1、退出管理系统
====================
请选择0-6:
选1后按回车,显示:
*************************
*通讯录链表的建立*
*************************
请顺序输入编号、姓名、性别、电话和地址
-------------------------------------------------------------------
第4章.设计心得
添加功能:
通讯者信息的查重
基本思想如下:
调用查找函数找出姓名相同的两个通讯者,对其中一个进行修改以示不同。
其基本算法如下:
voidcheckagain(LinkListhead)
{
ListNode*p;
P=ListFind(head);
If(p=NULL){
Printf(“没有查到要修改的通讯者\n”);
Return;
}
Else
{
Printf(“编号姓名性别电话地址\n”);
Printf(“---------------------------------------\n”);
Printf(“%s,%s,%s,%s\n”,p->data.num,p->data.name,p->data.sex,p->data.phone,p->data.addr);
Printf(“------------------------------------------\n”);
Printf(“输入该通讯者正确的姓名”);
}
}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 课程 实践 通讯录 程序 报告