链表的操作.docx
《链表的操作.docx》由会员分享,可在线阅读,更多相关《链表的操作.docx(14页珍藏版)》请在冰豆网上搜索。
链表的操作
链表的操作
1.课程设计的目的
1.掌握线性链表的基本性质。
2.掌握线性链表的存储结构与基本操作的实现。
2.课程设计的要求
1.利作链表的插入运算建立线性链表,然后利用链表的查找、删除、计数、输出等运算反复实现链表的这些操作(插入、删除、查找、计数、输出单独写成函数的形式),并能在屏幕上输出操作前后的结果。
2.利用线性链表实现对用户输入的一组数据进行插入排序。
3.课程设计报告内容
3.1运行环境
联想计算机,WindowsXP操作系统,MS-DOS窗口,borlandc++builder6.0
3.2算法设计的思想
ADTlistis
Operations:
*createlist():
Input:
alinklist
Preconditions:
datainputfromoperator;endupwith‘*’
Process:
scanf("%d",&ch);//读人新数据;
p=(linklist*)malloc(sizeof(linklist));//申请新结点;
p->data=ch;
p->next=NULL;
r->next=p;
r=r->next;
ch=getchar();
Output:
alinklist
Postconditions:
none
*insertnode(linklist*head,charx,inti)
Input:
list,x,i
Preconditions:
creatalinklist
Process:
s=(linklist*)malloc(sizeof(linklist));
s->data=x;
s->next=p->next;
p->next=s;
p=head;
Output:
p
Postconditions:
none
*deletelist(linklist*head,inti)
Input:
Aninfixexpression
Preconditions:
None
Process:
Output:
Postconditions:
*deletelist(linklist*head,inti)
Input:
list,i
Preconditions:
creatalinklist
Process:
r=p->next;
p->next=r->next;
free(r);
Output:
p
Postconditions:
none
locatelist(linklist*head,charx):
Input:
list,x
Preconditions:
creatalinklist
Process:
while((p!
=NULL)&&(p->data!
=x))
{
p=p->next;
i++;
}
Output:
i
Postconditions:
none
lengthlist(linklist*head):
Input:
list
Preconditions:
creatalinklist
Process:
while(p->next!
=NULL)
{
p=p->next;
i++;
}
Output:
i
Postconditions:
none
voidout_put(linklist*p):
Input:
list
Preconditions:
None
Process:
while(p!
=NULL)
{
printf("%c",p->data);
p=p->next;
}
Output:
p
Postconditions:
voidinsertsorting(linklist*head):
Input:
list
Preconditions:
creatalinklist
Process:
while(s!
=NULL)
{
q=p;
while(q!
=s)
{
if(s->datadata)
{
i=s->data;
s->data=q->data;
q->data=i;
}
q=q->next;
}
s=s->next;
}
Output:
Postconditions:
EndADTlist
3.3算法流程图
1.在主函数中提供用户输入的提示信息,根据用户的需求,调用相应的函数。
输入创建链表
2.各函数具体算法请见算法分析;
3.4算法设计分析
1.建立链表:
动态的申请新的结点,不断地将新的结点插入表尾,修改表尾指针;最后返回表头指针;
2.插入:
此程序采用前插,需要*p的前趋*q,然后再完成在*q之后插入*s的后插。
P
3.删除:
删除*p需要先找到*p的前趋结点*q,然后完成指针的变化操作即可;
4.查找:
此程序采用按值查找法,从第一个结点起判断当前结点的值是否等于给定值,若找到则返回该结点地址,否则继续下一个结点;若整个表中未找到则返回NULL;
5.计数:
只要设一个移动指针扫描整个链表,就可以统计出元素个数即表长;
6.输出:
类似求表长,设一个移动指针扫描整个链表,将扫描到的值逐个输出,并且在其余几个函数中可反复调用此函数;
7.插入排序:
从第一个结点开始逐个比较交换;
3.5源代码
#include
#include
typedefchardatatype;
typedefstructnode{
datatypedata;
structnode*next;
}linklist;
linklist*p;
linklist*createlist(void)//建立链表;
{
charch;
linklist*head;
linklist*p,*r;
head=(linklist*)malloc(sizeof(linklist));//申请头结点;
head->next=NULL;
r=head;
ch=getchar();//ch为建立与否标志;
while(ch!
='*'){//"*"为输入数据结束符号;
scanf("%d",&ch);//读人新数据;
p=(linklist*)malloc(sizeof(linklist));//申请新结点;
p->data=ch;
p->next=NULL;
r->next=p;
r=r->next;
ch=getchar();
}
return(head);
}
linklist*insertnode(linklist*head,charx,inti)//在链表第i位插入值为x的结点
{
intj=0;
linklist*p,*s;
p=head;
while(p&&jp=p->next;
++j;
}
if(!
p||j>i-1)
exit
(1);
s=(linklist*)malloc(sizeof(linklist));
s->data=x;
s->next=p->next;
p->next=s;
p=head;
returnp;
}
linklist*deletelist(linklist*head,inti)//删除链表第i位的结点
{
intj=0;
linklist*p,*r;
p=head;
while(p&&jp=p->next;
++j;
}
if(p->next!
=NULL)
{
r=p->next;
p->next=r->next;
free(r);
}
p=head;
returnp;
}
intlocatelist(linklist*head,charx)//查找;
{
inti=1;
linklist*p;
p=head->next;
while((p!
=NULL)&&(p->data!
=x))
{
p=p->next;
i++;
}
returni;
}
intlengthlist(linklist*head)//求表长;
{
inti=0;
linklist*p;
p=head;
while(p->next!
=NULL)
{
p=p->next;
i++;
}
returni;
}
voidout_put(linklist*p)//输出链表;
{
while(p!
=NULL)
{
printf("%c",p->data);
p=p->next;
}
printf("\n");
}
voidinsertsorting(linklist*head)//利用利用线性链表实现插入排序
{
linklist*p,*s,*q;
chari;
p=head->next;
s=p->next;
while(s!
=NULL)
{
q=p;
while(q!
=s)
{
if(s->datadata)
{
i=s->data;
s->data=q->data;
q->data=i;
}
q=q->next;
}
s=s->next;
}
out_put(p);
}
voidmain()
{
linklist*list;
inty,i;
charx;
linklist*p;
cout<<"输入字符建立一个单链表并以'*'号结尾:
\n";
list=createlist();
cout<<"----------------------";
cout<<"\n1.插入\n2.删除\n3.查找\n4.计数\n5.输出\n6.进行插入排序\n";
cout<<"----------------------";
cout<<"\n\n请输入您要进行的操作的序号:
";cin>>y;
if(y==1)
{
cout<<"您想在第几位插入字符:
";cin>>i;
cout<<"您想插入的字符是:
";cin>>x;
cout<<"原链表为:
";
out_put(list);
p=insertnode(list,x,i);
cout<<"在第"<
";
out_put(p);
}
elseif(y==2)
{
cout<<"您想在第几位删除字符:
";cin>>i;
cout<<"原链表为:
";
out_put(list);
p=deletelist(list,i);
cout<<"在第"<
";
out_put(p);
}
elseif(y==3)
{
cout<<"您想查找的字符是:
";cin>>x;
i=locatelist(list,x);
cout<<"您要查找的字符位置是:
"<
}
elseif(y==4)
{
i=lengthlist(list);
cout<<"此链表的表长为:
"<
}
elseif(y==5)
{
cout<<"输出建立的链表:
";
out_put(list);
}
elseif(y==6)
{
cout<<"插入排序按降序排列后的有序表为:
";
insertsorting(list);
}
}
3.6运行结果
3.7算法调试
1.在动态插入链表后应将指针设置p=head;,因为此时指针指向最后一个结点,打印出的是逆序
2.删除链表中
if(!
p->next||j>i-1)
exit
(1);这句多余,永远访问不到
3.在输出打印中判断条件while(p->data!
='*')越界了,因为p可能为NULL,改为while(p!
=NULL)或者while(p)
4.总结
通过实验更清楚的了解到在单链表中插入和删除元素只需修改有关结点的指针域内容,不需要像顺序表那样移动元素,很好的降低了运算的时间复杂度。
同时复习动态指针的生成,并注意到运行过程中指针的逻辑位置。
将课本知识转化为自己的理解和概念。
只有真正理解整个流程,才能很好的运用到设计中,在写程序之前先想好方案,画流程图,不仅让自己的思路更清楚,还能节省不少的时间。
在参阅参考资料中设计的程序时,通过对实例的分析,更加了解循环语句的应用,同时也了解系统提供的一些子程序的功能,能更好的将这些功能应用于自己的设计中。
将程序设计好以后,很大一部分时间在调试,不断思考和修改程序。
此设计是在实验报告的基础上进行修改和优化,像是判断时用的if…else…语句,在原来的报告中对每个用户操作的判断都用if这样使得已经找到符合条件的语句进行操作后还得进行下面语句的判断,加长了程序运行中不必要的时间,因此在此设计中适当加入else就减少了不必要的判断时间。
当程序能正常运行之后,又在思考怎样将程序写得更简洁、清晰,同时也考虑到用户面对程序操作的方便,于是加入提示信息的函数。
课程设计考验我们对一整个C++程序设计各语句各功能的综合应用,在脑海中形成一个框架,系统地将个模块,逻辑结构组合起来,了解一整个运作的流程.
参考文献
[1]谭浩强.C++面向对象程序设计.-3版.北京:
清华大学出版社,2006.1
[2]刘振安.C程序设计课程设计[M].北京:
机械工业出版社,2004.9.127-148.
[3]宁正元,王秀丽.算法与数据结构.北京:
清华大学出版社,2006.1