【C语言】单链表的顺序插入及节点删除

目录

一、顺序插入

1、步骤:

2、图示:

3、具体实现

4、示例

二、节点删除

1、步骤:

2、图示:

3、具体实现

4、示例


一、顺序插入

1、步骤:

(1)比较大小找到插入的位置;

(2)将插入点上一节点的指针指向新节点;

(3)将新节点的指针指向插入点的后一节点。

2、图示:

new为新节点地址;

last为上一节点地址;

temp为后一节点地址;

3、具体实现

        指针temp依次指向链表中的每个节点,并将节点的值与输入的值比较,如果不满足,temp则指向下一个。last保存上一次temp的值(即上一节点地址)。如图,当temp指向4这个节点时满足,则新节点位置为last和temp之间。然后将last节点的指针指向new,将new节点的指针指向temp。即:

last->next = new;		//插入位置的前一节点的指针指向新节点
new->next = temp;		//新节点的指针指向后一节点

4、示例

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

/*顺序插入法*/

/*声明结构体*/
struct NUM
{
	int num;
	struct NUM *next;
};

/*添加节点*/
void AddStruct(struct NUM **head,int ipnum)
{
	struct NUM *new; 	//保存新节点地址
	struct NUM *temp;	//当前地址
	struct NUM *last;	//上一节点地址
	
	last = NULL;

	new = (struct NUM *)malloc(sizeof(struct NUM));//创建节点
	if(new == NULL)
	{
		printf("内存分配失败\n");
		exit(1);
	}	

	//printf("内存分配成功\n");
	new->num = ipnum; 	 //保存数据到新节点
	
	if(*head != NULL)//不是空链表
	{
		
		temp = *head; //传入的是指针的地址即指针的指针,取值即可得到指针
		//printf("不是空链表\n");
		while(temp != NULL && ipnum > temp->num) //指针没有指到链表结尾且插入值大于当前节点值
		{
			last = temp;			//保存插入位置前一节点地址,该节点的指针指向新节点
			temp = temp->next;		//指针往后走
		}

		if(ipnum <= (*head)->num) //如果输入的数值小于或等于第一个节点的值
		{
			new->next = *head;	//新节点的指针指向插入前的第一个节点
			*head = new;		//头指针指向新节点 (相当于头插法)
		}
		else
		{
			last->next = new;		//插入位置的前一节点的指针指向新节点
			new->next = temp;		//新节点的指针指向后一节点
		}	
	}
	else //是空链表
	{
		printf("是空链表\n");
		*head = new;
		new->next = NULL;
	}
}


/*打印链表数据*/
void PrintfStruct(struct NUM *head)
{
	struct NUM *numh;
	numh = head;
	
	printf("输入的数据为:\n");
	
	while(numh != NULL)
	{
		printf("%d ",numh->num);
		numh = numh->next;  //指向下一个节点
	}

	printf("\n");

}
	

int main()
{
	struct NUM *head = NULL;
	int inpnum;
	while(1)
	{	
		printf("请输入数值(-1结束):");
		scanf("%d",&inpnum);
		if(inpnum == (-1)) break;
		
		AddStruct(&head,inpnum);
	}

	PrintfStruct(head);
	return 0;
}

二、节点删除

1、步骤:

(1)比较值找到要删除的节点;

(2)将删除点上一节点的指针指向后一节点;

(3)释放该节点空间。

2、图示:

last为上一节点地址;

temp为要删除节点的地址;

3、具体实现

        指针temp依次指向链表中的每个节点,并将节点的值与输入的值比较,如果不满足,则指向下一个。last保存上一次temp的值(即上一节点地址)。找到删除点后,将last节点的指针指向删除点temp的后一节点(temp->next);再释放temp节点。即

lats->next = temp->next;
free(temp);

4、示例

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

/*单链表删除*/

/*声明结构体*/
struct NUM
{
	int num;
	struct NUM *next;
};

/*添加节点*/
void AddStruct(struct NUM **head,int ipnum)
{
	struct NUM *new; 	//保存新节点地址
	struct NUM *temp;	//当前地址
	struct NUM *last;	//上一节点地址
	
	last = NULL;

	new = (struct NUM *)malloc(sizeof(struct NUM));//创建节点
	if(new == NULL)
	{
		printf("内存分配失败\n");
		exit(1);
	}	

	//printf("内存分配成功\n");
	new->num = ipnum; 	 //保存数据到新节点
	
	if(*head != NULL)//不是空链表
	{
		
		temp = *head;	//传入的是指针的地址即指针的指针,取值即可得到指针
		//printf("不是空链表\n");
		while(temp != NULL && ipnum > temp->num)  //指针没有指到链表结尾且插入值大于当前节点值
		{
			last = temp;			//保存插入位置前一节点地址,该节点的指针指向新节点
			temp = temp->next;		//指针往后走
		}

		if(ipnum <= (*head)->num) //如果输入的数值小于或等于第一个节点的值
		{
			new->next = *head;	//新节点的指针指向插入前的第一个节点
			*head = new;		//头指针指向新节点 (相当于头插法)
		}
		else
		{
			last->next = new;		//插入位置的前一节点的指针指向新节点
			new->next = temp;		//新节点的指针指向后一节点
		}	
	}
	else //是空链表
	{
		printf("是空链表\n");
		*head = new;
		new->next = NULL;
	}
	
	
}

/*删除节点*/
void DeleteStruct(struct NUM **head,int ipnum)
{
	struct NUM *temp;
	struct NUM *last;

	temp = *head; 
	last = NULL;
	while(temp != NULL && ipnum != temp->num)  //指针没有指到链表结尾且插入值不等于当前节点值
	{
		last = temp;			//保存插入位置前一节点地址,该节点的指针指向新节点
		temp = temp->next;		//指针往后走
	}
	
	if(temp == NULL)
	{
		printf("找不到该节点!\n");
	}
	else
	{
		if(last == NULL) //该值在第一个节点(上面的while不执行)
		{
			*head = temp->next; //头指针指向后一节点
		}
		else
		{
			last->next = temp->next;	//上一节点的指针指向后一节点
		}
		free(temp);  //释放空间
		printf("已删除该节点!\n");
		
	}


}
/*打印链表数据*/
void PrintfStruct(struct NUM *head)
{
	struct NUM *numh;
	numh = head;
	
	printf("链表中数据为:\n");
	
	while(numh != NULL)
	{
		printf("%d ",numh->num);
		numh = numh->next;  //指向下一个节点
	}

	printf("\n");

}
	

int main()
{
	struct NUM *head = NULL;
	int inpnum;
	while(1)
	{	
		printf("请输入数值(-1结束):");
		scanf("%d",&inpnum);
		if(inpnum == (-1)) break;
		
		AddStruct(&head,inpnum);
		PrintfStruct(head);
	}


	printf("开始删除节点:\n");
	while(1)
	{	
		printf("请输入数值(-1结束):");
		scanf("%d",&inpnum);
		if(inpnum == (-1)) break;
	 	DeleteStruct(&head,inpnum);
		
		PrintfStruct(head);
	}
	return 0;
}

  • 2
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是 C 语言单链表的逆置、有序性插入和归并的代码实现: ## 单链表逆置 ```c struct ListNode* reverseList(struct ListNode* head) { struct ListNode* prev = NULL; struct ListNode* cur = head; while (cur) { struct ListNode* next = cur->next; cur->next = prev; prev = cur; cur = next; } return prev; } ``` 逆置单链表可以采用迭代或递归的方式实现。上面的代码实现了迭代逆置单链表的方法,具体思路是从头节点开始,每次取出当前节点,将其 next 指针指向前驱节点,然后将前驱节点和当前节点都向后移动一个位置。 ## 单链表有序性插入 ```c struct ListNode* insert_node(struct ListNode* head, int val){ struct ListNode* new_node = (struct ListNode*)malloc(sizeof(struct ListNode)); new_node->val = val; new_node->next = NULL; if (!head){ return new_node; } if (val < head->val){ new_node->next = head; return new_node; } struct ListNode* cur = head; while (cur->next && cur->next->val < val){ cur = cur->next; } new_node->next = cur->next; cur->next = new_node; return head; } ``` 有序性插入是将一个新节点插入到一个有序单链表中,使得插入后的单链表仍然保持有序。在有序单链表中,每个节点的值都是按照一定的顺序排列的,通常是从小到大或者从大到小。在这段代码中,我们首先判断链表是否为空,如果为空则直接返回新节点。如果新节点的值小于链表节点的值,则将新节点插入到头节点之前。否则,我们从头节点开始遍历单链表,找到待插入节点的位置,然后将新节点插入到该位置。 ## 单链表归并排序 ```c struct ListNode* merge_list(struct ListNode* l1, struct ListNode* l2) { struct ListNode* dummy = (struct ListNode*)malloc(sizeof(struct ListNode)); struct ListNode* cur = dummy; while (l1 && l2) { if (l1->val < l2->val) { cur->next = l1; l1 = l1->next; } else { cur->next = l2; l2 = l2->next; } cur = cur->next; } cur->next = l1 ? l1 : l2; return dummy->next; } struct ListNode* sort_list(struct ListNode* head) { if (!head || !head->next) { return head; } struct ListNode* slow = head; struct ListNode* fast = head->next; while (fast && fast->next) { slow = slow->next; fast = fast->next->next; } struct ListNode* l1 = head; struct ListNode* l2 = slow->next; slow->next = NULL; l1 = sort_list(l1); l2 = sort_list(l2); return merge_list(l1, l2); } ``` 归并排序是一种经典的排序算法,它的核心思想是分治和合并。在单链表中,我们可以通过快慢指针将单链表分成两个子链表,然后递归地对子链表进行排序,最后将两个有序子链表合并成一个有序链表。 上面的代码实现了归并排序的过程。在 `sort_list` 函数中,我们首先判断链表是否为空或只有一个节点,如果是则直接返回链表。否则,我们使用快慢指针找到链表的中间节点,将链表分成两个子链表,然后递归地对子链表进行排序。在 `merge_list` 函数中,我们使用类似于归并排序的方法将两个有序链表合并成一个有序链表

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值