【c语言】链表操作总结(创建,插入(排序),删除,比较,查找)+多习题套用

昨天加今天写代码都异常顺利,开心开心!!

讲正事了,今天相当于是对链表知识的总结了:
一个题目贯穿始末,同时在分析每一部分时,会给出相应例题,希望能对您有所帮助(*^▽^*)

题目:

创建结构体,包括学生的学号和成绩,创建链表,完成以下操作:

1.插入指定学生信息(学号:331,成绩:28)

2.删除指定学生信息(学号:333,成绩:22)

3.查找成绩高于20分的学生

4.找出成绩相同的同学

5.释放堆区空间

题解:

一、结构体的创建:
struct student 
{
	char no[10];
	float score;
	struct student *next;
};
  可用例题:

有一个链表,设结点中包含学号、成绩及指向下一结点的结构体指针;写一函数实现:输出成绩高于平均成绩的学生学号。(要求:给出结构体定义)

定义一个结构体管理士兵的信息(编号,姓名,兵种,年龄)。输入若干士兵的信息,当输入的士兵编号为0时输入结束。建立一个单向链表存放士兵信息并输出。(链表的建立和输出分别定义函数实现)

 

二、链表的创建:

关键代码:1.当头指针为空:head=p,r=p;   2.不为空时:r->next=p r=p;

图解:

代码如下:

student *create()
{
	student *head=NULL;
	student *p=NULL,*r=NULL;
	char no[10];
	while(1)
	{
		gets(no);
				if(strcmp(no,"0")==0) return head;//学号输0退出
		p=(student*)malloc(sizeof(student));//申请空间
		if(p==NULL)exit(0);
		strcpy(p->no,no);
		scanf("%f",&p->score);
		getchar();
			p->next=NULL;
		if(head==NULL)
		{
			head=p;
			r=p;
		}
		else{
			r->next=p;
			r=p;
		}
	}
	return head;
三、插入指定学生信息:(因为有进行比较的过程,所以该方法也适用于排序比较)

关键代码:1.头为空:head=newnode        2.newnode是它的首结点 :newnode->next=p;
    head=newnode;          3.不特殊:newnode->next=p; r->next=newnode; 

4.在结尾:r->next=newnode;newnode->next=NULL;

 代码如下:

student *insert(student *head,student *newnode)
{
student *r=NULL;student *p=head;
if(head==NULL)//为空链表时
{
	head=newnode;
newnode->next=NULL;
	return head;
}	
while(p)
{
	if(strcmp(p->no,newnode->no)>0)//寻找插入点,这里注意是插在前面的
	{
	if(p==head)//插在首节点的位置
	{
	newnode->next=p;
	head=newnode;	
	}	
	else
	{
		newnode->next=p;
		r->next=newnode;
	}
	return head;
	}
	r=p;
	p=p->next;
}
r->next=newnode;//插在最后
newnode->next=NULL;
return head;
} 
四、删除指定学生信息

关键代码:1.首即所找:head=p->next;         2.普通或结尾 :pre->next=p->next;(前驱结点)

图解:

 

代码如下:

student *del(student*head,char no[])
{
	student *p=NULL;
	student *pre=NULL;
	p=head;
	while(p)
	{
	if(strcmp(no,p->no)==0)
	{
		if(head==p)
		{
			head=p->next;
		}
		else{
			pre->next=p->next;
		}
		free(p);
		return head;
	}	
	pre=p;
	p=p->next;
	}
	printf("链表遍历完毕,未找到删除结点"); 
	return head;
}
 五、查找学生

关键代码:p=p->next;(感觉只有这一个诶)

void find(student *head)
{
	student *p=NULL;
	p=head;
	while(p)
	{
		if(p->score>20)
		{
			printf("恭喜,超过20分\n");
			puts(p->no);
			printf("%f",p->score);
			printf("\n\n"); 
		}
		p=p->next;
	}
	return;
}
 可用例题:

有一个链表,设结点中包含学号、成绩及指向下一结点的结构体指针;写一函数实现:输出成绩高于平均成绩的学生学号。(要求:给出结构体定义)

定义一个结构体管理士兵的信息(编号,姓名,兵种,年龄)。输入若干士兵的信息,当输入的士兵编号为0时输入结束。建立一个单向链表存放士兵信息并输出。(链表的建立和输出分别定义函数实现)
 

 六、找交集

关键代码:if(p1->data<p2->data)
             p1=p1->next;
        else if(p1->data>p2->data)
            p2=p2->next;(就在于发现不同后的移动)

node * getIntersection(node *h1,node *h2)
 {
 	node *p1=h1;
 	node *p2=h2;
 	node *head=NULL;
 	node *p=NULL;
 	node *r=NULL;
	while(p1&&p2)
	{
	 	if(p1->data<p2->data)
		 	p1=p1->next;
		else if(p1->data>p2->data)
			p2=p2->next;
		else if(p1->data==p2->data)
		{
			p=(node *)malloc(sizeof(node));
			p->data=p1->data;
			if(head==NULL)
			{
				head=p;
				r=p;
				head->next=NULL;//这里注意
			}
			else
			{
				r->next=p;
				r=p;
				r->next=NULL;//这里注意	
			}
			p1=p1->next;
			p2=p2->next;
		}		 	 	 
	 }
	 return head;
}

void printLinkedTable(node *head)
{ 
//这里输出NULL 
	if(head==NULL)
	{
		printf("NULL");
		return;
	}
  	node *p=NULL;
  	p=head;
  	while(p)
  	{
 	 	printf("%d ",p->data);
 	 	p=p->next;
 	}
}
可用例题:
已知两个非降序链表序列S1与S2,设计函数构造出S1与S2的交集新链表S3。 
 七、释放堆区空间

关键代码:next=p->next;  free(p);(后驱结点)

 

void freeAll(node * head)
 {
 	node *p=NULL, *next=NULL;
 	p=head;
 	while(p)
 	{
	 	next=p->next;
	 	free(p);
	 	if(!next)
	 	return;
	 	p=next;
	 }
 }

总代码!!

//链表的操作
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct student 
{
	char no[10];
	float score;
	struct student *next;
};

student *create()
{
	student *head=NULL;
	student *p=NULL,*r=NULL;
	char no[10];
	while(1)
	{
		gets(no);
				if(strcmp(no,"0")==0) return head;
		p=(student*)malloc(sizeof(student));
		if(p==NULL)exit(0);
		strcpy(p->no,no);
		scanf("%f",&p->score);
		getchar();
			p->next=NULL;
		if(head==NULL)
		{
			head=p;
			r=p;
		}
		else{
			r->next=p;
			r=p;
		}
	}
	return head;
}

student *insert(student *head,student *newnode)
{
student *r=NULL;student *p=head;
if(head==NULL)
{
	head=newnode;
newnode->next=NULL;
	return head;
}	
while(p)
{
	if(strcmp(p->no,newnode->no)>0)
	{
	if(p==head)
	{
	newnode->next=p;
	head=newnode;	
	}	
	else
	{
		newnode->next=p;
		r->next=newnode;
	}
	return head;
	}
	r=p;
	p=p->next;
}
r->next=newnode;
newnode->next=NULL;
return head;
} 

student *del(student*head,char no[])
{
	student *p=NULL;
	student *pre=NULL;
	p=head;
	while(p)
	{
	if(strcmp(no,p->no)==0)
	{
		if(head==p)
		{
			head=p->next;
		}
		else{
			pre->next=p->next;
		}
		free(p);
		return head;
	}	
	pre=p;
	p=p->next;
	}
	printf("链表遍历完毕,未找到删除结点"); 
	return head;
}
void find(student *head)
{
	student *p=NULL;
	p=head;
	while(p)
	{
		if(p->score>20)
		{
			printf("恭喜,超过20分\n");
			puts(p->no);
			printf("%f",p->score);
			printf("\n\n"); 
		}
		p=p->next;
	}
	return;
}

void display(student *head)
{
	student *p=head;
int i=0;
while(p)
{
	printf("创建的第%d个结点 ",++i);
	puts(p->no);
	printf("%f",p->score);
	printf("\n\n");
	p=p->next;
}
return;
}
void freeAll(student*head)
{

	 student *p=NULL, *next=NULL;
	 	p=head;
	 	while(p)
	 	{
		 	next=p->next;
		 	free(p);
		 	if(!next)
		 	return;
		 	p=next;
		 }
}

int main()
{
	student *head;
//创建链表 
	head=create();
	
//插入结点 
student *newnode=(student*)malloc(sizeof(student));
strcpy(newnode->no,"331"); 
newnode->score=27; 
head=insert(head,newnode); 
//输出链表
printf("删除前\n"); 
display(head);
//删除结点
char no[10];
//即将删除的结点 
strcpy(no,"333");
head=del(head,no);
printf("删除后\n");	
display(head);
//查找
find(head);
freeAll(head);
 return 0;
} ;
样例输入:
330
21
332
12
333
24
334
25
335
11
0
 结果:

 可用的例题还有很多,但我觉得领悟其中的精髓或许才是最好题解,感谢您的观看,希望对您有所帮助,祝您今天过得开心✿✿ヽ(°▽°)ノ✿(〃'▽'〃)!!!!!!不见不散~~~

  • 26
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值