1.链表节点的插入
struct student *insert(struct student *head,struct student *p)//节点插入
//p指向新节点的元素
{
struct student *q1,*q2;//q2为newstu前一节节点的地址,q1为newstu后一个节点的地址
q2=NULL;q1=head;
while(q1!=NULL&&q1->num<p->num)//q1=NULL时代表完成了遍历链表,&&后的那个条件为寻找符合条件的节点(这里是在学号升序排列的链表中将插入学生的学号排在正确的位置)
{
q2=q1;//q2为newstu前一节节点的地址,q1为newstu后一个节点的地址
q1=q1->next;//q1总是要比q2多一个节点长度;将newstu节点与q1节点进行比较,若条件(成立/不成立)则将q2节点变为newstu节点
}
if(q2==NULL)//在表头节点之前插入p
{
p->next=q1;//在q1前插入破,p指向q1
head=p; //head指向p
}else
{
if(q1==NULL)//在链表尾插入节点,所以newstu后面没有节点,所以不需要使newstu的指针域指向下一个元素
{
q2->next=p;//q1==NULL时、q2为最后一个节点;此时q2指向p,p就插在了q2后面,p就为最后一个元素
p->next=NULL;
} else//在链表中插入节点
{
p->next=q1;//将p节点插入p2与p1之间
q2->next=p;
}
}
return head;// 返回新的节点头地址(因为节点头可能更新)
}
2链表节点的删除
struct student *deletetable(struct student *head,int num)//删除节点
{
struct student *q1,*q2;//q2为newstu前一节节点的地址,q1为newstu后一个节点的地址
q2=NULL;
q1=head;
while(q1!=NULL&&q1->num!=num) //q1=NULL时代表完成了遍历链表,&&后的那个条件为寻找符合条件的节点(这里是在寻找学号为num的学生)
{
q2=q1;
q1=q1->next;
}
if(q2==NULL)//如果头结点就是要删除的节点,就将头结点地址进行更新
{
head=q1->next;
}else
{
if(q1!=NULL)//如果不是尾节点的话,就跳过q1节点,使q2节点的next直接指向q1.next
{
q2->next=q1->next;
}else
{
q2->next=NULL;
}
}
free(q1);//释放q1借鉴的内存
return head;//返回更新的头节点地址
}
继上篇:《已知节点数量的动态链表的创建、向链表中插入数据、遍历输出链表》的综合运用
已知节点数量的动态链表的创建、向链表中插入数据、遍历输出链表-CSDN博客文章浏览阅读26次。int num;//数据域(一个节点储存的数据)//指针域(用于指向下一个数据节点/下一个数据节点的地址)https://blog.csdn.net/qq_38965505/article/details/134223755?spm=1001.2014.3001.5501之后可以得到一个相对完整的具有增添和删除功能的链表
3.完整代码
#include <stdio.h>
#include <malloc.h>
struct student
{
int num;
char name[20];
float score;
struct student *next;
};
struct student *createtable(int n)
{
struct student *head,*p,*q;
int i;
head=NULL;
q=NULL;
for(i=0;i<n;i++)
{
p=(struct student*)malloc(sizeof(struct student));
scanf("%d %f\n",&p->num,&p->score);
gets(p->name);
p->next=NULL;
if(head==NULL)
{
head=p;
q=p;
}else
{
q->next=p;
q=p;
}
}
return head;
}
struct student *insert(struct student *head,struct student *p)
{
struct student *q1,*q2;
q2=NULL;q1=head;
while(q1!=NULL&&q1->num<p->num)
{
q2=q1;
q1=q1->next;
}
if(q2==NULL)
{
p->next=q1;
head=p;
}else
{
if(q1==NULL)
{
q2->next=p;
p->next=NULL;
} else
{
p->next=q1;
q2->next=p;
}
}
return head;
}
struct student *deletetable(struct stdent *head,int num)
{
struct student *q1,*q2;
q2=NULL;
q1=head;
while(q1!=NULL&&q1->num!=num)
{
q2=q1;
q1=q1->next;
}
if(q2==NULL)
{
head=q1->next;
}else
{
if(q1!=NULL)
{
q2->next=q1->next;
}else
{
q2->next=NULL;
}
}
free(q1);
return head;
}
void traverse(struct student* head)
{
struct student* p;
p=head;
while(p!=NULL)
{
printf("学号:%d,姓名:%s,分数:%4.2f\n",p->num,p->name,p->score);
p=p->next;
}
}
int main()
{
struct student *tablehead,*newstu;
int n=0,num;
printf("请输入n:");
scanf("%d",&n);
tablehead=createtable(n);
traverse(tablehead);
printf("请输入一个需要插入的学生信息:\n");
newstu=(struct student*)malloc(sizeof(struct student));
scanf("%d %f\n",&newstu->num,&newstu->score);
gets(newstu->name);
tablehead=insert(tablehead,newstu);
traverse(tablehead);
printf("请输入需要删除信息的学生学号:\n");
scanf ("%d",&num);
tablehead=deletetable(tablehead,num);
traverse(tablehead);
return 0;
}