p->next=str[i];
p=p->next;}
p->next=NULL;//将最后一个结点的next置为空
break;}
5.插入函数voidInsert(employ*L,inti)
首先新建一个结点employ*p,并分配内存给该结点p=(employ*)malloc(sizeof(employ)),再输入结点信息,当插入的位置为0时,将该结点插入到头结点之后,否则寻找到要插入位置的前一个结点,然后执行语句p->next=L->next;L->next=p;进行插入,若插入到最后一个位置则执行语句L->next=p;p->next=NULL;具体代码如下:
if(i==0){//当插入的位置为0时,则将该结点插入到头结点后
p->next=L->next;
L->next=p;}
else{
if(L->next!
=NULL){
L=L->next;
while(L!
=NULL&&j!
=i-1){//寻找插入位置
L=L->next;j++;}
}
3
计算机科学与技术系06级专升本班
if(L!
=NULL){//在中间任意位置插入
p->next=L->next;
L->next=p;}
if(j==Length(L)){//插入到最后一个结点之后
L->next=p;
p->next=NULL;}}
}
6.删除函数voidDelete(employ*L)
本函数是先按照编号查询到某个员工的信息显示出来,然后选择是否删除数据,若该员
工已离职则需删除该员工的信息,删除部分的代码如下所示:
if(x==1){//删除数据
q=p->next;//q指向p的下一个结点
p->next=q->next;//p指向q的下一个结点
free(q);//释放该结点
break;}
7.显示函数voidDisplay(employ*L)
当结点不为空时执行循环体,将结点信息显示出来,当结点为空时输出“当前没有任何
员工的信息!
”
四、上机调试
1.在上机调试的过程中,遇到了以下几个问题:
1.1在创建员工单链表时,没有遇到太大的问题,只是在输入员工的信息的时候,如果输
入的字符长度超过了系统定义的字符数组的长度,那么显示的时候就会出现错误,比如重复
的出现某一个关键字,后来增加了字符数组的长度,便解决了问题。
1.2在查询函数中有一个问题,就是只能查询一次,然后如果再进行查询的话,就会找不
到你所要找的信息,或者出现错误,经过查找,发现问题出在指针上,由于查询一次以后,
指针还是指向该位置,没有返回成原来的头结点,当在最后加上指针重新指向头结点以后,
就能进行多次查询了。
1.3在排序函数中,还是出现了比较多的问题,比如刚开始的时候,对多个数据进行排序
的时候,它所显示的数据并不是按关键字从小到大排序的,后来经过分析,知道是由于控制
的变量出现错误,因为是用冒泡法进行排序的,第二层循环的条件要根据第一层循环的变量
来写的,经过修改,排序是正确的,但是显示的时候又出现了错误的现象,它显示的还是老
的数据,也就是说新的数据根本就没有传过去,经过长时间的分析,发现指针那块还是出现
了问题,没有将新的数据链到单链表上,所以显示数据的时候,它还是指向老的数据链,经
修改,将指针指向新的数据链后,再显示,便能显示出最新的员工的信息。
1.4在插入函数中,调试也花了不少的时间,刚开始调试的时候,数据能够在除两头以外
的其他地方进行插入,但是当在尾结点后进行插入时,显示不出来数据,经过分析,在尾结
点后进行插入给予特殊的处理,如果是尾结点,就直接将最后一个结点指向新的结点,但是
如果在别的位置进行插入时,它没有进行判断位置是否正确,而是直接要求你输入新数据,
这跟实际情况不符,后来在此基础上增加了判断语句,如果插入的位置不正确,那么就直接
退出,重新输入,再进行调试,便实现了所有的可能出现的情况。
1.5最后是删除函数,在该部分进行调试时,问题不是很大,有一个小问题,就是如果将
所有的数据都删除完后,这时系统应该显示为空,但是系统没有任何说明,经过修改,在主
函数中,将头结点的尾指针置为空,如果没有任何员工的信息时,则增加一条判断语句,如
4
计算机科学与技术系06级专升本班
果头结点的尾指针置为空,则直接输出此系统没有任何信息,再进行调试,是正确的,可以
实现所有的功能。
2.算法的时间与空间性能分析
本设计中主要对插入算法和排序算法进行分析:
2.1时间性能分析
插入算法的时间复杂度为O(n),排序算法中最坏的情况下总的比较次数为:
n(n-1)/2,
2总的移动次数为:
3n(n-1)/2次,所以其时间复杂度为:
O(n)2.2空间性能分析
单链表中的每个结点都要增加一个指针空间,相当于增加了n个指针变量。
其空间复
杂度O(n),冒泡排序法的空间复杂度为:
O
(1),总体来讲整个算法的空间性能良好。
五、用户使用说明
首先创建一个单链表用于存储各员工的相关信息,然后按照提示的信息就可以进行查
询、更新、排序、删除等功能了。
1.运行程序时,首先出现一个界面,首先选择1.创建,创建一个单链表,将原有的员工信
息录入。
2.如果你想查询某个员工的信息,你就选择2.查询。
3.如果你要更新某个员工的信息,请选择3.更新。
4.如果你要对员工信息进行排序,请选择4.排序。
5.如果有新员工进入公司,你要插入该员工的信息,请选择5.插入。
6.如果有员工离职,需要删除该员工的信息,请选择7.删除。
7.每次调用一个函数后你想显示所有员工信息,请选择6.显示。
8.如果你输入的是非法字符时,系统会提示你重新输入。
六、测试结果
5
计算机科学与技术系06级专升本班
6
计算机科学与技术系06级专升本班
7
计算机科学与技术系06级专升本班
8
计算机科学与技术系06级专升本班
七、心得与体会
本次课程设计已经接近尾声,从这次课程设计中令我感触最深的是自己设计出来的东西
很有成就感,尽管做得不是很完善,但是毕竟是自己一点一点设计出来的。
刚开始拿到题目时觉得挺高兴的,因为题意很明显,属于那种一看到题目就知道大概需
要做什么的,可是实际设计起来就并不像想象中那么简单了,由于要求设计的函数比较多,
要一一实现的话还是比较困难的。
最终经过老师的指导、同学的帮助和自己的努力完成了此
次设计,尽管和实际之间还存在一段距离,但是它在一定程度上锻炼了我的动手能力。
八、参考书目
1.李春葆,数据结构习题与解析,清华大学出版社,2007年1月第一版2.胡学钢,数据结构,高等教育出版社,2004年1月第一版九、带注释的源程序
#include"iostream.h"
#include"string.h"
#include"stdio.h"
9
计算机科学与技术系06级专升本班
#include"malloc.h"
#definemax1000//定义最大的数组下标#defineNULL0//定义NULL为0typedefstructnode{//定义员工结构体
charnum[10];//编号
charname[10];//姓名
charsex[4];//性别
charbirthdate[20];//出生年月
chardegree[20];//学历
charposition[20];//职务
chartelnum[20];//电话
charaddress[100];//住址
node*next;//指针域
}employ;
intLength(employ*L){//求单链表的长度
intn=0;
while(L!
=NULL){//当单链表不为空时
L=L->next;//指向下一个结点
n++;}//计算单链表的长度
returnn;//返回单链表的长度}
voidCreate(employ*L,intm){//创建函数
charnum[10],name[10],sex[4],birthdate[20],degree[20],position[20],
telnum[20],address[100];
inti=0,j=0,k=0;
employ*M;//新建一个结点
while(icout<<"请输入第"<
"<cout<<"-------------------------------------------------------"<cout<<"编号姓名性别出生年月学历职务电话住址"<cout<<"-------------------------------------------------------"<cin>>num;//输入编号
cin>>name;//输入姓名
cin>>sex;//输入性别
cin>>birthdate;//输入出生年月
cin>>degree;//输入学历cin>>position;//输入职务
cin>>telnum;//输入电话
cin>>address;//输入住址
M=(employ*)malloc(sizeof(employ));//分配内存给该结点
strcpy(M->num,num);//将姓名值赋给新结点的姓名
strcpy(M->name,name);//将编号值赋给新结点的编号
strcpy(M->sex,sex);//将性别值赋给新结点的性别
strcpy(M->birthdate,birthdate);//将出生年月值赋给新结点的出生年月
10
计算机科学与技术系06级专升本班
strcpy(M->degree,degree);//将学历值赋给新结点的学历
strcpy(M->position,position);//将职务值赋给新结点的职务
strcpy(M->telnum,telnum);//将电话值赋给新结点的电话
strcpy(M->address,address);//将住址值赋给新结点的住址
M->next=NULL;//新结点的指针域置为空
L->next=M;//将新结点链到单链表上
L=M;//指向新结点
i++;}
}
voidDisplay(employ*L){//显示函数
while(L->next!
=NULL){//当结点不为空时,执行循环
L=L->next;//指向结点
cout<num<<"";
cout<name<<"";
cout<sex<<"";
cout<birthdate<<"";
cout<degree<<"";
cout<position<<"";
cout<telnum<<"";
cout<address<<""<if(L->next=NULL)//当第一个结点为空时
cout<<"当前没有任何员工的信息!
"<}
voidShow(employ*L){//显示某一个结点函数cout<num<<"";//输出编号,姓名,性别,出生年月,学历,职务,电话,住址
cout<name<<"";
cout<sex<<"";
cout<birthdate<<"";
cout<degree<<"";
cout<position<<"";
cout<telnum<<"";
cout<address<<""<}
voidSearch(employ*L){//查询函数
employ*p;
p=L;//p指向头结点
intx;
charnum[10],name[10],telnum[20],address[100];
while
(1){
cout<<"1.按编号查找2.按姓名查找"<cout<<"3.按电话查找4.按住址查找"<cout<<"5.退出"<cout<<"请选择:
(1,2,3,4,5)"<cin>>x;
11
计算机科学与技术系06级专升本班
L=L->next;//指向第一个结点
if(x==1){
cout<<"请输入要查找员工的编号:
"<cin>>num;
while(L!
=NULL){//当结点不为空时,执行循环
if(strcmp(L->num,num)==0){//如果结点中有与输入相符合的信息
Show(L);//显示该结点信息
break;}
elseL=L->next;}//指向下一个结点
if(L==NULL)
cout<<"不存在该员工的信息,请重新输入:
"<L=p;}//指回头结点
elseif(x==2){
cout<<"请输入要查找员工的姓名:
"<cin>>name;
while(L!
=NULL){//当结点不为空时,执行循环
if(strcmp(L->name,name)==0){//如果结点中有与输入相符合的信息
Show(L);//显示该结点信息
break;}
elseL=L->next;}//指向下一个结点
if(L==NULL)
cout<<"不存在该员工的信息,请重新输入:
"<L=p;}//指回头结点
elseif(x==3){
cout<<"请输入要查找员工的电话号码:
"<cin>>telnum;
while(L!
=NULL){//当结点不为空时,执行循环
if(strcmp(L->telnum,telnum)==0){//如果结点中有与输入相符合的信息
Show(L);//显示该结点信息
break;}
elseL=L->next;}//指向下一个结点
if(L==NULL)
cout<<"不存在该员工的信息,请重新输入:
"<L=p;}//指回头结点
elseif(x==4){
cout<<"请输入要查找员工的住址:
"<cin>>address;
while(L!
=NULL){//当结点不为空时,执行循环
if(strcmp(L->address,address)==0){
Show(L);//显示该结点信息
break;}
elseL=L->next;}//指向下一个结点
if(L==NULL)
cout<<"不存在该员工的信息,请重新输入:
"<12
计算机科学与技术系06级专升本班
L=p;}//指回头结点
elseif(x==5)
break;
else
cout<<"你输入的为非法字符,请重新输入:
"<}
voidUpdata(employ*L){//更新函数
charnum[10];
intx;
charname[10],sex[4],birthdate[20],degree[20],position[20],
telnum[20],address[100];
cout<<"请输入要更新员工的编号:
"<cin>>num;
L=L->next;//指向第一个结点
while(L!
=NULL){//当结点不为空时,执行循环
if(strcmp(L->num,num)==0){//如果结点中有与输入相符合的信息
Show(L);//显示该结点信息
break;}
elseL=L->next;}//指向下一个结点
if(L==NULL)//当结点为空时
cout<<"不存在该员工的信息,请重新输入:
"<else{//当结点不为空时
while
(1){
cout<<"1.更新数据2.退出"<cout<<"请选择:
(1,2)"<cin>>x;
if(x==1){
cout<<"请输入新数据:
"<cin>>num;//输入编号
cin>>name;//输入姓名
cin>>sex;//输入性别
cin>>birthdate;//输入出生年月
cin>>degree;//输入学历
cin>>position;//输入职务
c