系本人原创,转载请注明出处:https://blog.csdn.net/coder_what/article/details/82685205
程序设计老师让写一个链表的综合运用,包括创建,查看某个节点,删除某个节点,插入某个节点,以及链表的逆序,还必须要有出错提示和返回。QaQ,,,看见这么多东西我就想嘤嘤嘤,
先放上链表的结构体:
typedef struct student
{
int num;
char name[10];
char sex;
struct student* next;
}Stu;
关于老生常谈的链表创建,直接放源码了啦啦啦:
Stu* p1,*p2;//p2属于中间临时变量
n=0;
if((p1=p2=(Stu*)malloc(LEN))==NULL)
{
printf("Malloc Error!");
}
printf("\n\t\tPlease input the number, name and sex for students (it will be end when inputing 0) :\n");
scanf("%d%s%*c%c",&p1->num,p1->name,&p1->sex);
while(p1->num!=0)
{
n++;
if(n==1)
head=p1;
else
p2->next=p1;
p2=p1;
if((p1=(Stu *)malloc(LEN))==NULL)
{
printf("Malloc Error!");
}
scanf("%d%s%*c%c",&p1->num,p1->name,&p1->sex);
}
p2->next=NULL;
return head;
此处要注意的是p2只是一个临时的结构体指针,暂时储存p1的值,然后p1再去开辟空间。
还需要注意的一点是scanf中字符串和字符在一起时的处理,%s和%c之间要加一个%*c去吸收一个空格
打印链表就不说了,一直指向下一个next,直到空指针为之就OK了。
对于查看某个节点或者删除某个节点的时候,需要加一个node变量,用来计算链表的节点数,下面就放上删除某个节点的代码了:
Stu* del(Stu*head)
{
Stu* p1,*p2;
p2=p1=head;
int num,k=0,node=1;
if(head==NULL)
{
printf("\n\t\t\tPlease creat a single linked list pressing No.1");
getchar();
getchar();
return head;
}
printf("\n\t\t\tPlease input the node you wanna delete:");
scanf("%d",&num);
for(;node!=num;node++,p1=p1->next)
if(p1->next==NULL)
{
node=1;
p1=head;
printf("\n\t\t\tYour number is wrong, please input again:");
scanf("%d",&num);
if(node==num) break;
}
node=1;
p1=head;
while(p1!=NULL)
{
if(node==num&&k==0)
{
head=p1->next;
break;
}
if(node==num&&k!=0)
p2->next=p1->next;
p2=p1;//p2指向p1的上一个节点
p1=p1->next;
k++;
node++;
}
system("cls");
printf("\n\t\t\tOK!");
getchar();
getchar();
return head;
}
这里有一个节点数输错的报错并返回机制:我可是想了好久才想到的,,,囧
方法就是先用一个for循环(当输入的节点数和node不相等时继续循环),当链表遍历完毕后,如果还不相等就提示出错并返回重新输入。此处p2的作用和创建链表时的作用一样。
接着就是插入某一节点的链表哈~(输入0表示插入到链表的第一位),源码奉上:
Stu* insert(Stu * head)
{
Stu* p1,*p2;
p1=head;
int num,node=0;
if(head==NULL)
{
printf("\n\t\t\tPlease creat a single linked list pressing No.1");
getchar();
getchar();
return head;
}
if((p2=(Stu*)malloc(LEN))==NULL)
{
printf("Malloc Error!");
}
printf("\n\t\t\tPlease input the node you wanna insert(the first inputing 0):");
scanf("%d",&num);
for(;node!=num;node++,p1=p1->next)//出错机制
if(p1==NULL)
{
p1=head;
node=0;
printf("\n\t\t\tYour node is wrong, please input again:");
scanf("%d",&num);
if(node==num) break;
}
p1=head;
node=1;
printf("\n\t\t\tPlease input the number, name and sex you wanna insert:");
scanf("%d%s%*c%c",&p2->num,p2->name,&p2->sex);
while(p1!=NULL)
{
if(num==0)
{
p2->next=head;
head=p2;
break;
}
if(node==num&&num!=0)
{
p2->next=p1->next;
p1->next=p2;
break;
}
p1=p1->next;
node++;
}
system("cls");
printf("\n\t\t\tOK!");
getchar();
getchar();
return head;
}
此处p2 的作用是插入的那个节点。
刚开始学习链表的时候觉得插入最难,其实逆序比插入难好多(╯▽╰):
刚开始我只定义了一个指针就想逆序成功,结果成功被打脸,然后最后写了伪代码才知道,需要三个结构体指针才行╭(╯^╰)╮
具体的办法如下滴:
先令p2=p1->next;
然后p1->next=NULL;
p3=p2->next;
p2->next=p1;
然后再令p1=p3->next;开始循环
值得注意的时,每指向下一个时都需要检验是否为空哦。
放上代码:
Stu* reverse(Stu*head)
{
Stu *p1, *p2, *p3;
p1=head;
if(head==NULL)
{
printf("\n\t\t\tPlease creat a single linked list pressing No.1");
getchar();
getchar();
return head;
}
p2=p1->next;
p1->next=NULL;
if(p2==NULL)
{
printf("\n\t\t\tOK!");
getchar();
getchar();
return p1;
}
while(1)
{
p3=p2->next;//
p2->next=p1;
if(p3==NULL)
{
head=p2;break;
}
p1=p3->next;//
p3->next=p2;
if(p1==NULL)
{
head=p3;break;
}
p2=p1->next;//
p1->next=p3;
if(p2==NULL)
{
head=p1;break;
}
}
system("cls");
printf("\n\t\t\tOK!");
getchar();
getchar();
return head;
}
这就完成逆序了啦啦啦