c语言链表大例题.docx
《c语言链表大例题.docx》由会员分享,可在线阅读,更多相关《c语言链表大例题.docx(11页珍藏版)》请在冰豆网上搜索。
c语言链表大例题
#include
#include
#include
#include
#defineTRUE1
#defineFALSE0
#defineINPUT1
#defineSHOW2
#defineREMOVE3
#defineINSERT4
#defineSORT5
#defineREVANGE6
#defineEXIT7
typedefstructPOINT
{
intx,y;//x和y分别存储点的横、纵坐标值
structPOINT*next;//next用以指向下一个同类实例(节点)
}POINT;
POINT*InputPoints(void);
voidshowPointLink(POINT*head);
voidshowOnePoint(POINT);
voiddestroyLink(POINT*head);
POINT*searchPrePoint(POINT*head,intx,inty);
intremovePoint(POINT**head);
voidsortPointByX(POINT*head);
POINT*revangePointLink(POINT*head);
voidinsertPoint(POINT**head);
voidshowMenu(void);
intselectedAction(void);
voidsayGoodBye(void);
voidsayGoodBye(void)
{
inti;
printf("\n\n\n\n\n\n");
for(i=0;i<3;i++)
{
printf("欢迎您的使用!
\n按任意键继续...\n");
getch();
printf("请您多提宝贵意见!
\n按任意键继续...\n");
getch();
printf("祝您身体健康!
\n按任意键继续...\n");
getch();
printf("谢谢使用!
\n按任意键继续...\n");
getch();
printf("不送了!
\n按任意键继续...\n");
getch();
printf("请您走好!
\n按任意键继续...\n");
getch();
printf("不要忘了我哦!
!
!
\n按任意键继续...\n");
getch();
printf("再见!
\n按任意键继续...\n");
getch();
}
}
intselectedAction(void)
{
intchoose=0;
while(choose<1||choose>7)
{
showMenu();
choose=getche();
if(choose<'1'||choose>'7')
choose=0;
else
choose-='0';
if(choose==0)
{
printf("\n输入错误!
");
printf("\n请重新选择(1-7)");
getch();
}
}
returnchoose;
}
voidshowMenu(void)
{
system("cls");
printf("\n\n屏幕上的点点的管理信息系统\n");
printf("\n1)录入信息");
printf("\n2)显示信息");
printf("\n3)删除信息");
printf("\n4)插入信息");
printf("\n5)排序");
printf("\n6)逆序");
printf("\n7)退出");
printf("\n请选择:
");}
voidinsertPoint(POINT**h)
{
intNewx,Newy,Oldx,Oldy;
POINT*p,*q;
printf("插入前:
");
showPointLink(*h);
//1、确定新点坐标;
printf("请输入新点坐标:
");
scanf("%d%d",&Newx,&Newy);
p=(POINT*)malloc(sizeof(POINT));
p->x=Newx;
p->y=Newy;
p->next=NULL;
//2、确定插入点坐标;
printf("再输入插入点坐标:
");
scanf("%d%d",&Oldx,&Oldy);
//3、查找插入点的前驱节点;
q=searchPrePoint(*h,Oldx,Oldy);
//4、插入节点。
if(q==NULL)
{
p->next=*h;
*h=p;
}
elseif(q->next==NULL)
q->next=p;
else
{
p->next=q->next;
q->next=p;
}
printf("插入后:
");
showPointLink(*h);
}
POINT*revangePointLink(POINT*h){
POINT*p,*q;
printf("逆序前:
");
showPointLink(h);
if(h)
{
p=h;
h=h->next;
p->next=NULL;
while(h)
{
q=h;
h=h->next;
q->next=p;
p=q;
}
}
printf("逆序后:
");
showPointLink(p);
returnp;
}
voidsortPointByX(POINT*h)
{
POINT*p,*q,t,*r;
printf("\n排序前的结果是:
");
showPointLink(h);
printf("\n");
for(p=h;p;p=p->next)
for(q=p->next;q;q=q->next)
if(p->x>q->x)
{
t=*p;
*p=*q;
*q=t;
r=p->next;
p->next=q->next;
q->next=r;
}
printf("\n排序后的结果是:
");
showPointLink(h);
printf("\n");
}
//if(!
removePoint(Head))这是主函数中调用该函数的语句
intremovePoint(POINT**h)
{
/*该函数的操作应分为3步:
1、输入要删除的点的坐标;
2、查找该点的前驱节点;
3、删除该点。
*/
intx,y,Ok=TRUE;
POINT*p,*q;
//1、输入要删除的点的坐标;
printf("\n\n\n这是删除功能\n原有点坐标如下:
\n");
showPointLink(*h);
printf("\n请输入要删除的点的坐标:
");
scanf("%d%d",&x,&y);
//2、查找该点的前驱节点;
p=searchPrePoint(*h,x,y);
if(p==NULL)//删除第一个点
{
q=*h;//将h所指向的空间的值(Head的值,第一节点的首地址),
//赋值给q,使得q指向第一节点
*h=q->next;//将q所指向的实例的next成员的值,赋值给h所
//指向的空间(Head),使得Head指向第二节点
free(q);//释放第一节点
}
elseif(p->next==NULL)
Ok=FALSE;//要删除的点根本不存在
else//要删除的点是出了第一个节点之外的其它链中的节点
{
q=p->next;//1、让q指向要删除的点:
p->next=q->next;//2、更改p所指向的节点的链域的指向,
//使其指向q所指向的下一个节点
free(q);//3、释放该删除的节点
}
showPointLink(*h);
returnOk;
}
POINT*searchPrePoint(POINT*h,intx,inty)
{
POINT*p;
for(p=NULL;h&&(h->x!
=x||h->y!
=y);h=h->next)
p=h;
returnp;
/*
该函数用以查找坐标值为x和y的节点的前驱节点;其返回值有三种可能性:
1、返回值为NULL:
意味着要查找的坐标是第一个节点,第一个节点肯定
没有前驱节点,因此返回值为NULL也是合理的。
2、返回值不为NULL,但返回值所指向的节点的next成员的值为NULL:
在链表的所有节点中,不存在坐标值为(x,y)的节点。
3、上述条件都不满足:
成功的返回了要找节点的前驱节点。
*/
}
voiddestroyLink(POINT*h)
{
POINT*p;
while(h)
{
p=h;//让p指向h所指向的节点;
h=h->next;//让h向后移动;
free(p);//释放p所指向的节点;
}
}
voidshowOnePoint(POINTnode)
{
printf("<%d,%d>",node.x,node.y);
}
//showPointLink(Head);
voidshowPointLink(POINT*h)
{
printf("\n链表的内容如下:
\n");
for(;h;h=h->next)
showOnePoint(*h);//此处,函数showOnePoint()需要的参数类型
//是POINT,而当前函数相关内容是h,而其类型是POINT*,需要将POINT*//转换成POINT类型,因此需要对h进行指向运算,以取得其所指向的实例。
printf("\n");
}
POINT*InputPoints(void)
{
intx,y;
POINT*head=NULL,*p,*q;
printf("请输入一个点的两个坐标");
printf("任意坐标值为0,则表示输入结束\n");
scanf("%d%d",&x,&y);//先从键盘输入一对坐标
while(x&&y)//只要有一个为0,则停止输入。
{
p=(POINT*)malloc(sizeof(POINT));
p->x=x;
p->y=y;
p->next=NULL;
if(head==NULL)
head=p;
//只有第一次进入循环时,head的值为NULL;当第一次申请一个节点,
//则该节点是未来整个链表的第一个节点,而它的首地址就是整个链表
//的首地址,应该赋值给head.
else
q->next=p;//1号
/*由于下面的话,说明q现在正好指向最后一个节点,只要将刚刚申请的,p所指向的节点链接到最后一个节点的后面,即可完成任务。
*/
q=p;//2号
/*q每次都在本轮循环结束之前指向刚刚申请且刚刚链到链表的末尾的那个
新节点(简单地说,q总指向链表的最后一个节点。
上述的1号语句和2号语句的书写顺序与执行顺序不同,总是先执行2号,再执行1号。
*/
scanf("%d%d",&x,&y);//从键盘输入一对坐标
}
returnhead;//从前面的描述中可知,若head指向第一个节点,则
//返回该节点的首地址,就等于返回链表首地址;若一开始输入的//数据中包含0,则head的初始值为NULL,此时返回值为NULL。
}
voidmain(void)
{
POINT*Head=NULL;
intchoice=0;
while(choice!
=7)
{
choice=selectedAction();
system("cls");
switch(choice)
{
caseINPUT:
if(Head)//表示该链表非空,应该先清空!
destroyLink(Head);
Head=InputPoints();
printf("录入完成!
\nPressanykeytocontinue...");
getch();
break;
caseSHOW:
showPointLink(Head);
printf("显示完毕!
\nPressanykeytocontinue...");
getch();
break;
caseREMOVE:
if(removePoint(&Head)==FALSE)
printf("删除的点不存在!
");
printf("删除完毕!
\nPressanykeytocontinue...");
getch();
break;
caseINSERT:
insertPoint(&Head);
printf("插入完毕!
\nPressanykeytocontinue...");
getch();
break;
caseSORT:
sortPointByX(Head);
printf("排序完毕!
\nPressanykeytocontinue...");
getch();
break;
caseREVANGE:
Head=revangePointLink(Head);
printf("逆序完毕!
\nPressanykeytocontinue...");
getch();
break;
caseEXIT:
sayGoodBye();
break;
}
}
destroyLink(Head);
Head=NULL;
}