链表的插入操作

小甲鱼链表插入:
对链表的插入是指将一个结点插入到一个已有的链表中。

为了能做到正确插入,必须解决两个问题:
①怎样找到插入的位置;
②怎样实现插入。

我们可以先用指针变量p0指向待插入的结点,p1指向第一个结点,将p0->num与p1->num相比较,如果p0->num > p1->num,此时将p1后移,并使p2指向刚才p1所指的结点。
流程图如下,左边三个都是插入到链表中间(不是表头或表尾),右上角是插入到表头,右下角是插入到表尾。
在这里插入图片描述
流程图如下:
在这里插入图片描述

源码:

#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>

#define LEN sizeof(struct student)//student结构的大小

struct student *creat();//创建链表
struct student *del(struct student *head,int num);//del函数用于删除结点,*head即链表 
                                                  //的头指针,num是要删除的结点num。
                                                
struct student *insert (struct student *head,struct student *stu_2);//第一个参数需要被插入的链表
                                                                    //第二个参数待插入的结构的地址 
void print(struct student *head);//打印链表

struct student
{
	int num;
	float score;
	struct student *next;											  
};

int n;//全局变量,用来记录存放了多少数据。

void main()
{
	struct student *stu,*p,stu_2;
	int n;
	
	stu = creat();//返回head指针 
	p = stu;
	print(p);//打印输出 
	
	printf("\nPls input the num to delete: ");
	scanf("%d",&n);
	print(del(p,n));//把head指针和n传进去del函数里面,调用完后再次打印,
	                //提示:每当调用完删除或者插入函数后,都要返回head重新打印一次 
	
	printf("\nPls input the num to insert: ");
	scanf("%d",&stu_2.num);
	printf("Pls input the score: ");
	scanf("%f",&stu_2.score);
	
	p=insert(stu,&stu_2);//调用插入函数,把head和stu_2的地址传进insert函数里面 
	print(p);
	
	printf("\n\n");
	system("pause");
}

struct student *creat()//把数据调进仓库里面 
{
	struct student *head;
	struct student *p1,*p2;
	
	p1 = p2 = (struct student *)malloc(LEN);//LEN是student结构的大小
	
	printf("Pls enter the num: ");
	scanf("%d",&p1->num);
	printf("Pls enter the score: ");
	scanf("%f",&p1->score);
	
	head = NULL;
	n = 0;
	
	while(p1->num)
	{
		n++;
		if(1 == n)
		{
			head = p1;
		}
		else 
		{
			p2->next = p1;
		}
		
		p2 = p1;
		p1 = (struct student *)malloc(LEN);//->
		//新建一个student数据结构的对象,为其分配student结构所占用的内存空间。
		//sizeof(struct student)为求该对象在内存中占用多少内存空间,然后用malloc函数分配同样大小的空间。
		//将指针p1指向该对象,即新分配出的空间。 
		
		printf("\nPls enter the num: ");
		scanf("%d",&p1->num);
	    printf("Pls enter the score: ");
	    scanf("%f",&p1->score);
	} 
	
	p2->next = NULL;
	
	return head;
} 

void print(struct student *head)//把数据从仓库调出,此时无需要p1、p2等指针,直接用p 
{
	struct student *p;
	printf("\nThere are %d records!\n\n",n);
	
	p = head;
	if(head)//如果输入的第一个学号就是0,既直接把NULL赋给head 
	{
		do
		{
			printf("学号为 %d 的成绩是:%f\n",p->num,p->score);
			p = p->next;//直接用p顺延下去 
		}while(p);//倘若p的next为NULL,既p=0,结束循环 
	}
}

struct student *del(struct student *head ,int num)
{
	struct student *p1,*p2;
	
	if(NULL == head)//如果头指针指向NULL,这是一个空链表。 
	{
		printf("\nThis list is NULL\n");
		goto end;
	}
	
	p1 = head;//从头结点开始寻找 
	while(p1->num != num && p1->next != NULL)//如果第一个结点的学号不是要删除的学号,而且存在第二个结点
	                                         //则使p2指向p1,再让p1顺延下去,直到找到要删除的数据为止。 
	{
		p2 = p1;
		p1 = p1->next;
	}
	if(num == p1->num)
	{
		if(p1 == head)      //当将要删除的结点位于头结点的时候 
		{
			head = p1->next;//直接跳过p1(head)指向的数据,让head指向p1的next 
		}
		else                //一般情况:如果要删除的数据不是头结点的数据 
		{
			p2->next = p1->next;//跳过p1当前指向的数据,直接让p2的next指向p1的next 
		}
		
		printf("\nDelete No: %d succeed!\n",num);
		n = n-1;//n是作为一个全局变量,用来记录链表的数据数。 
	}
	else
	{
		printf("%d not been found!\n",num);
	}
	
end:
	return head;
}

struct student *insert(struct student *head,struct student *stu_2)
{
	struct student *p0,*p1,*p2;
	
	p1=head;
	p0=stu_2;
	if(NULL==head)//如果是空表的话 
	{
		head=p0;
		p0->next = NULL;
	}
	else          //如果不是空表的话 
	{
		while((p0->num > p1->num) && (p1->next != NULL))//两种情况退出while,如果是要插入的
		                                                //元素p0比链表中任何一个元素都要大,既
														//要插到表尾,则退出while,因为此时p1的
														//next是空指针NULL。 
		{
			p2=p1;
			p1=p1->next;
		}
		
		if(p0->num <= p1->num)
		{
			if(head == p1)  //p1是头结点,插入头部 
			{
				head = p0;
			}
			else            //普通情况,插入中间 
			{
				p2->next=p0;//在p1指向了p1的next以后,p2的next要指向新插入的元素 
			}
			
			p0->next = p1;
		}
		else                //p0->num > p1->num,既p0的num最大,插入到末尾 
		{
			p1->next = p0;
			p0->next = NULL;
		}
	}
	
	n=n+1;                 //由于插入了,所以增加了一位数据成员到链表中 
	
	return head;
}				

在这里插入图片描述
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值