小甲鱼 P47 单链表3---单链表插入和删除

小甲鱼 P47 单链表3---单链表插入和删除

单链表和数组相比较,最大的优势是插入元素到指定位置的效率。

(单链表插入)让用户输入若干个整数,按顺序插入单链表之中:

比如将3插入2和4之间。对于单链表,改变指针就可以了。先抹掉2指向4的指针,将2改为指向3,3指向4,两个步骤。

代码如下:

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

struct Node
{
	int value;
	struct Node *next;
};

void insertNode(struct Node **head, int value)
{
	struct Node *previous;
	struct Node *current;
	struct Node *neww;//新的节点 
	
	//头指针 
	current = *head;
	previous = NULL;
	
	//PS:找到符合条件就不进入循环了 
	while (current != NULL && current->value < value)//循环,迭代查找匹配节点
	{
		//current=NULL有三种情况:
		//1、没找到,传进来是空的单链表 
		//2、没找到,找到最后都没有找到合适的位置,指向末尾位置
		//3、找到了 
		previous = current;//previous记录current的上一个地址 
		current = current->next;//current记录current的下一个节点 
	}
	
	//申请内存空间来存放新的节点 
	neww = (struct Node *)malloc(sizeof(struct Node));
	if (neww == NULL)
	{
		printf("内存分配失败!\n");
		exit(1);
	}
	
	neww->value = value;
	neww->next = current;
	
	//下面有两种特殊的情况 	 
	//1、空的单链表
	//2、通常情况,在夹在中间  
	if (previous == NULL)
	{
		//当while不被执行时,空的单链表
		*head = neww;//直接插入到第一个节点位置 
	}
	else
	{
		//通常情况,在夹在中间
		previous->next = neww;
	}
}

void printNode(struct Node *head)
{
	struct Node *current;
	
	current = head;
	while (current != NULL)
	{
		printf("%d ", current->value);
		current = current->next;
	}
	
	putchar('\n');
}

int main(void)
{
	struct Node *head = NULL;
	int input;
	
	while (1)
	{
		printf("请输入一个整数(输入-1表示结束):");
		scanf("%d", &input);
		if (input == -1)
		{
			break;
		}
		insertNode(&head, input);
		printNode(head);
	}
}

单链表删除

比如将刚插入的3删除。对于单链表,改变指针就可以了。先抹掉指向3的指针,再抹掉指向4的指针,将2改为指向4。

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

struct Node
{
	int value;
	struct Node *next;
};

void insertNode(struct Node **head, int value)
{
	struct Node *previous;
	struct Node *current;
	struct Node *neww;//新的节点 
	
	//头指针 
	current = *head;
	previous = NULL;
	
	//PS:找到符合条件就不进入循环了 
	while (current != NULL && current->value < value)//循环,迭代查找匹配节点
	{
		//current=NULL有三种情况:
		//1、没找到,传进来是空的单链表 
		//2、没找到,找到最后都没有找到合适的位置,指向末尾位置
		//3、找到了 
		previous = current;//previous记录current的上一个地址 
		current = current->next;//current记录current的下一个节点 
	}
	
	//申请内存空间来存放新的节点 
	neww = (struct Node *)malloc(sizeof(struct Node));
	if (neww == NULL)
	{
		printf("内存分配失败!\n");
		exit(1);
	}
	
	neww->value = value;
	neww->next = current;
	
	//下面有两种特殊的情况 	 
	//1、空的单链表
	//2、通常情况,在夹在中间 
	if (previous == NULL)
	{
		//当while不被执行时,空的单链表
		*head = neww;//直接插入到第一个节点位置 
	}
	else
	{
		//通常情况,在夹在中间
		previous->next = neww;
	}
}

void printNode(struct Node *head)
{
	struct Node *current;
	
	current = head;
	while (current != NULL)
	{
		printf("%d ", current->value);
		current = current->next;
	}
	
	putchar('\n');
}

void deleteNode(struct Node **head, int value)
{
	struct Node *previous;
	struct Node *current;
	
	//头指针 
	current = *head;
	previous = NULL;
	
	//PS:找到符合条件就不进入循环了 
	while (current != NULL && current->value != value)//循环,迭代查找匹配节点 
	{
		previous = current;//previous记录current的上一个地址 
		current = current->next;//current记录current的下一个节点 
	}
	
	//下面有两种特殊的情况 :找不到 和 找到 
	if (current == NULL)//找不到 
	{
		//找不到也有两种情况: 
		//1、空链表,没有节点 
		//2、单链表节点所有遍历过后,节点value与参数value没有匹配的
		//此时current指向单链表的末尾
		printf("找不到匹配的节点!\n");
		return;//使整个函数结束	 
	}
	else//找到了 
	{
		//找到了也有两种情况 
		//1、待删除的节点 在 第一个节点的位置 
		if (previous == NULL)
		{
			*head = current->next;
		}
		else//2、通常情况,在夹在中间 
		{
			previous->next = current->next;
		}
		free(current);
	}
}

int main(void)
{
	struct Node *head = NULL;
	int input;
	
	printf("开始测试插入整数..\n"); 
	while (1)
	{
		printf("请输入一个整数(输入-1表示结束):");
		scanf("%d", &input);
		if (input == -1)
		{
			break;
		}
		insertNode(&head, input);
		printNode(head);
	}
	
	printf("开始测试删除整数..\n"); 
	while (1)
	{
		printf("请输入一个整数(输入-1表示结束):");
		scanf("%d", &input);
		if (input == -1)
		{
			break;
		}
		deleteNode(&head, input);
		printNode(head);
	}
	
}

猜你喜欢

转载自blog.csdn.net/xiaodingqq/article/details/82937306