课 程 设 计
课程设计名称: 数据结构课程设计
专 业 班 级 : 计科××××
学 生 姓 名 : ×××
学 号 : ××××××
指 导 教 师 :
课程设计时间:
计算机应用技术 专业课程设计任务书
学生姓名 ××× 专业班级 计科×× 学号 ××××
题 目 ××××××××××
课题性质 A 课题来源 D
指导教师 同组姓名 无
主要内容 学习掌握并熟练运用C语言进行程序设计;
针对具体应用问题,选择、设计和实现合适的抽象数据类型;
进行简单的需求分析,给出设计方案。
任务要求
综合运用和融化所学理论知识,提高分析和解决实际问题的能力,达到培养良好程序设计能力和习惯的目的,为开发满足问题要求的小型应用软件奠定基础,达到软件工程的综合性基础训练的目的。
完成需求分析报告,报告中对关键部分给出图表说明。要求格式规范,工作量饱满。
参考文献 《数据结构(C语言版)》严蔚敏 清华大学出版社
《C语言程序设计》(第三版)谭浩强 清华大学出版社
审查意见
指导教师签字:
教研室主任签字: 年 月 日
1 需求分析
手机通讯录系统,以联系人为节点建立伪队列(有头尾指针、且可从表中间进行操作),要实现一下基本功能。
增加联系人
删除联系人
修改联系人
清空通讯录
查找联系人
按分组显示联系人
显示全部联系人
退出系统
2概要设计
(1) 程序总体框架如图1所示:
图1 程序框架图
(2)序中各函数程简单说明见如表1函数说明所示:
返回值 函数名 参数表 函数说明 提供客户
int main void 主函数 是
void initAddressBook LinkQueue &Q 初始化通讯录 否
bool enAddressBook LinkQueue &Q 增加联系人 是
bool update LinkQueue &Q 修改联系人 是
bool delPerson LinkQueue &Q 删除联系人 是
bool findByName LinkQueue &Q 查找联系人 是
bool findByGroup LinkQueue &Q 按组显示 是
void disAll LinkQueue &Q 显示全部联系人 是
bool clearAddressBook LinkQueue &Q 清空通讯录 是
表1 函数说明
(2)对程序中的各个函数功能的描述
① 主函数main:
系统开始、结束界面的显示、各个功能函数的调用、转换以及参数的传递、定义通讯头结点并传递给各个功能函数
② 初始化通讯录函数initAddressBook:
初始化主函数传入的头结点,即初始化通讯录,此系统采用伪队列,有头、尾指针,可从中间进行删除操作
③ 增加联系人函数enAddressBook
增加联系人到通讯录的尾部,返回增加是否成功。
④ 修改联系人函数
按照用户提供的联系人姓名修改联系人所有信息,返回修改是否成功。
⑤ 删除联系人
按照用户指定的联系人姓名删除相应联系人信息,返回删除是否成功。
⑥ 查找联系人
按照用户提供的联系人姓名查找第一个合法姓名对应的信息,查找成功则显示信息,失败则提示无此联系人,返回是否查找到。
⑦ 按组显示函数
按照用户提供的分组名称,查找组中联系人,若存在则全部输出,若不存在则提示无此分组,返回是否超找到合法联系人。
⑧ 显示全部联系人函数
显示当前通讯录中所有联系人的信息,若为空通讯录,则显示无联系人。
⑨ 清空通讯录
删除所有联系人信息,返回是否成功!
⑩ 通讯录人数函数
判断通讯录当前联系人数量,返回之,此函数主要是为清空通讯录函数所调用,故不提供给用户。
计3 运行环境
1)软件环境
操作系统:Windows7
2)硬件环境
处理器:Intel Pentium 166MX 或更高
内存:32MB以上
硬盘空间:1GB以上
显卡:SVGA 显示适配
4 开发工具和编程语言
Microsoft visual C++
C语言
5 详细设
//主函数
int main()
{
LinkQueue Q;
initAddressBook(Q);
int flag=0;
while(flag!=8)
{
printf("※※※※※主※※※※※菜※※※※※单※※※※※\n");
printf("※1、增加联系人 2、删除联系人 ※\n");
printf("※3、修改联系人 4、清空通讯录 ※\n");
printf("※5、查找联系人 6、按组显示 ※\n");
printf("※7、显示全部联系人 8、退出 ※\n");
printf("※※※※※※※※※※※※※※※※※※※※※※※\n");
printf("请输入编号(1-8):\n");
scanf("%d",&flag);
if(flag<1||flag>8)
{
printf("输入错误请重新输入!\n");
continue;
}
else
{
switch(flag){
case 1:
if(enAddressBook(Q))
printf("增加联系人成功!\n");
else
printf("增加联系人失败!\n");
break;
case 2:
if(delPerson(Q))
printf("删除联系人成功!\n");
else
printf("联系人删除失败!\n");
break;
case 3:
if(update(Q))
printf("修改联系人成功!\n");
else
printf("修改联系人失败!\n");
break;
case 4:
if(clearAddressBook(Q))
printf("通讯录已清空!\n");
else
printf("通讯录清空失败!\n");
break;
case 5:
findByName(Q);
break;
case 6:
findByGroup(Q);
break;
case 7:
disAll(Q);
break;
case 8:
system("cls");
break;
}
}
}
printf("※※※※※感谢您使用本系统!※※※※※※\n");
return 0;
}
//初始化通讯录
void initAddressBook(LinkQueue &Q)
{
Q.front=Q.rear=(QNode *)malloc(sizeof(QNode));
if(!Q.front)
exit(1);
else
Q.front->next=NULL;
}
//清空通讯录
bool clearAddressBook(LinkQueue &Q)
{
system("cls");
while(addressBookLength(Q)!=0)
{
QNode *p;
p=Q.front->next;
Q.front->next=p->next;
if(p==Q.rear)
Q.rear=Q.front;
free(p);
}
return true;
}
//通讯录当前人数
int addressBookLength(LinkQueue &Q)
{
int i=0;
QNode *p;
p=Q.front;
if(Q.front==Q.rear)
i=0;
else
{
while(p!=Q.rear)
{
p=p->next;
i++;
}
}
return i;
}
//删除联系人
bool delPerson(LinkQueue &Q)
{
char _name[20];
system("cls");
printf("请输入要删除的联系人的姓名:\n");
scanf("%s",_name);
QNode *p,*q;
if(Q.front==Q.rear)
{
printf("通讯录为空!\n");
return false;
}
else
{
p=Q.front;
q=Q.front->next;
while(q!=Q.rear){
if(strcmp(q->name,_name)==0)
{
p->next=q->next;
free(q);//删除节点
return true;
}
else
{
p=p->next;
q=q->next;
}
}
if((strcmp(q->name,_name)==0))
{
free(q);
Q.front=Q.rear;
return true;
}
else
{
printf("无此联系人!\n");
return false;
}
}
}
//查找联系人
bool findByName(LinkQueue &Q)
{
system("cls");
if(Q.front==Q.rear)
{
printf("手机中无联系人!\n");
return false;
}
else
{
char _name[20];
printf("请输入要查询的联系人姓名:\n");
scanf("%s",_name);
QNode *p;
p=Q.front->next;
while(p->next!=NULL)
{
if(strcmp(p->name,_name)==0)
{
printf("姓名:%s 号码:%s 分组:%s\n",p->name,p->tel,p->group);
return true;
}
p=p->next;
}
if(strcmp(p->name,_name)==0){
printf("姓名:%s 号码:%s 分组:%s\n",p->name,p->tel,p->group);
return true;
}
else
{
printf("查无此人!\n");
return false;
}
}
}
//按组显示联系人
bool findByGroup(LinkQueue &Q)
{
system("cls");
if(Q.front==Q.rear)
{
printf("手机中无联系人!\n");
return false;
}
else
{
char _group[20];
printf("请输入要查询的分组:\n");
scanf("%s",_group);
QNode *p;
p=Q.front->next;
while(p->next!=NULL)
{
if(strcmp(p->group,_group)==0)
{
printf("姓名:%s 号码:%s \n",p->name,p->tel);
}
p=p->next;
}
if(strcmp(p->group,_group)==0){
printf("姓名:%s 号码:%s \n",p->name,p->tel);
return true;
}
else
{
printf("无此分组!\n");
return false;
}
}
}
//增加联系人
bool enAddressBook(LinkQueue &Q)
{
system("cls");
QNode *p;
p=(QNode *)malloc(sizeof(QNode));
if(!p)
return false;
else
{
printf("请输入联系人姓名:\n");
scanf("%s",p->name);
printf("请输入联系人号码:\n");
scanf("%s",&p->tel);
printf("请输入联系人分组:\n");
scanf("%s",p->group);
if(Q.front->next==NULL)
{
Q.front->next=p;
Q.rear=p;
Q.rear->next=NULL;
}
else
{
p->next=NULL;
Q.rear->next=p;
Q.rear=p;
}
return true;
}
}
//修改联系人
bool update(LinkQueue &Q)
{
system("cls");
if(Q.front==Q.rear)
{
printf("手机中无联系人!\n");
return false;
}
else
{
char _name[20];
printf("请输入要修改的联系人姓名:\n");
scanf("%s",_name);
QNode *p;
p=Q.front->next;
while(p->next!=NULL)
{
if(strcmp(p->name,_name)==0)
{
printf("请输入新联系人姓名:\n");
scanf("%s",p->name);
printf("请输入新联系人号码:\n");
scanf("%s",&p->tel);
printf("请输入新联系人分组:\n");
scanf("%s",p->group);
return true;
}
p=p->next;
}
if(strcmp(p->name,_name)==0){
printf("请输入新联系人姓名:\n");
scanf("%s",p->name);
printf("请输入新联系人号码:\n");
scanf("%s",&p->tel);
printf("请输入新联系人分组:\n");
scanf("%s",p->group);
return true;
}
else
{
printf("查无此人!\n");
return false;
}
}
}
//显示所有联系人
void disAll(LinkQueue &Q)
{
system("cls");
int i=0;
QNode *p;
p=Q.front->next;
if(Q.front==Q.rear)
printf("无联系人!\n");
else
{
printf(" 姓名 号码 分组\n");
while(p!=NULL){
printf("%15s %15s %15s\n",p->name,p->tel,p->group);
p=p->next;
}
}
}
6 调试分析
1.测试中的问题举例:
在测试删除联系人函数时发现无论通讯录中现存多少条记录只要删除一条之后,通讯录就会被清空,经过检查发现是删除函数中的条件控制设置有错,导致只要一删除一个联系人就会事头结点与尾结点指向同一个,导致再显示联系人时显示无联系人。经过调整已处理好。
2.算法改进设想举例:
程序中还有很多地方不能很好的模拟通讯录的功能,比如在增肌联系人时,不管原来新联系人姓名是否已存在,都会被加入通讯录,这样一来就有可能重复记录。此外在查找联系人时只要查找到一个合法记录就会中断查找操作,如此有可能导致记录的漏查。结合以上两点应优化增加查找联系人算法,在存入之间进行防重判断。
7 测试结果
1.测试数据举例:
姓名 手机号 分组
张三 12345678910 家人
李四 12345678911 朋友
王五 12345678912 朋友
赵六 12345678913 同学
表2 测试数据举例
2.按如下顺序进行测试:
1) 将测试数据逐条输入通讯录(测试增加联系人函数)
2) 显示全部联系人(测试显示联系人函数)
3) 选择一个联系人进行修改(测试修改联系人函数)
4) 显示全部联系人(验证修改联系人函数是否有效)
5) 选择一个联系人进行查找(测试查找联系人函数)
6) 选择一个多人分组进行按分组显示(测试按分组显示函数)
7) 选择清空联系人(测试清空联系人函数)
8) 显示全部联系人(验证清空联系人函数)
9) 选择退出(退出程序)
3、按照如上提供的测试步骤得出以下结果运行图:
主菜单如图2所示:
图2 运行示例图a
1)在菜单中选择“1”将测试数据逐条输入通讯录,如图3
图3 运行示例图b
2) 在菜单中选择“7”显示全部联系人,如图4
图4 运行示例图c
3) 在菜单中选择“3”选择一个联系人进行修改,如图5
图5 运行示例图d
4) 在菜单中选择“7”显示全部联系人,如图6
图6 运行示例图e
5) 在菜单中选择“5”选择一个联系人进行查找,如图7
图7 运行示例图f
6) 在菜单中选择“6”选择一个多人分组进行按分组显示,如图8
图8 运行示例图g
7) 在菜单中选择“4”清空联系人,如图9
图9 运行示例图h
8) 在菜单中选择“7”显示全部联系人,如图10
图10 运行示例图i
9) 在菜单中选择“8”,退出,如图11
图11 运行示例图j
参考文献
[1]严蔚敏,《数据结构(C语言版)》 清华大学出版社
[2]谭浩强.《C语言程序设计》(第三版) 清华大学出版社
[3]Peter Van Der Linden ,C专家编程,人民邮电出版社
[4]Kenneth A.Reek C和指针 ,人民邮电出版社
心得体会
通过这次数据结构实践作业,我更深刻的体会到了C语言的语句简洁性、紧凑性,与数据结构思想对于一个程序编码顺利进行的重要性。
语言是程序的骨肉,而数据结构和算法即使程序的灵魂,要想成功的编写程序必须选好合适的数据结构,比如这次课程设计中,最开始我准备用普通的线性表进行设计,后来发现那样很不方便,后来改为用“伪队列”之后就方便了许多。
另外,我觉得比较重要的一点是在编复杂程序时要有宏观思想,想从整体把握设计好各个板块的调用关系,最好先做出一个流程图,再按照这个总体设想进一步具体、细化!这样才不会在需要调用其它函数时手忙脚乱!
此外,进行如上所述的操作前提都是以扎实的语言基础做为前提的,在最开始的代码编辑阶段,我曾被指针很深的困扰,后来对此一节找了些资料进行“补课”,自己也进行的深入的理解,后来才逐渐顺利起来!
信息科学与工程 学院课程设计成绩评价表
课程名称:数据结构课程设计
设计题目:×××××
专业:计科 班级:××× 姓名:××× 学号:××××××
序号 评审项目 分 数 满分标准说明
1 内 容 思路清晰;语言表达准确,概念清楚,论点正确;实验方法科学,分析归纳合理;结论严谨,设计有应用价值。任务饱满,做了大量的工作。
2 创 新 内容新颖,题目能反映新技术,对前人工作有改进或突破,或有独特见解
3 完整性、实用性 整体构思合理,理论依据充分,设计完整,实用性强
4 数据准确、可靠 数据准确,公式推导正确
5 规 范 性 设计格式、绘图、图纸、实验数据、标准的运用等符合有关标准和规定
6 纪 律 性 能很好的遵守各项纪律,设计过程认真;
7 答 辩 准备工作充分,回答问题有理论依据,基本概念清楚。主要问题回答简明准确。在规定的时间内作完报告。
总 分
综
合
意
见
指导教师 年 月 日
温馨提示:答案为网友推荐,仅供参考