C语言实现链表模板(非伪代码)

 对于所有的代码务必自己实现一遍

主要内容:链表的创建,销毁,链表的增删改查,链表的遍历

1、结构体定义:链表节点/链表

typedef struct  ListNode{ //创建链表单独结点
	int data; //数值域
	struct ListNode* next; //下一个结点的指针域
}ListNode;

typedef struct LinkedList { //完整的链表
	struct ListNode* head; //头结点,也就是一个单独结点
	int len; //长度
}LinkedList;

 2、创建一个链表

void Creat_LinkedList(LinkedList* list) //创建一个链表
{
	//把头节点置空,长度置为0
	list->head = NULL;
	list->len = 0;
}

3、销毁一个链表

void Destroy_LinkList(LinkedList* list) //销毁一个链表
{
	while (list->head) //当头节点不为空时
	{
		ListNode* temp = list->head; //用一个临时的结点指向此时的头节点
		list->head = list->head->next; //将指针指向头指针的下一个结点
		free(temp); //把临时变量释放,也就把此时的结点释放
	}
	list->len = 0; //链表长度归0;
}

3.1:销毁链表的图解。

4、插入一个节点

//在链表中插入一个元素,在第i个位置插入value值
void Insert_LinkList(LinkedList* list, int i, int value)
{
	if (i<0 || i>list->len) //位置越界
	{
		printf("插入失败");
		return;
	}
	//表明位置合法:1.创建结点->改变指针方向
	ListNode* newNode=(ListNode*)malloc(sizeof(ListNode));
	newNode->data = value;//把数据赋值给新创建的数值域

	if (i == 0) //表明需要在头头节点的位置插入元素(即改变头指针的指向),使用头插法
	{
		newNode->next = list->head; //新生成的结点,指向链表头
		list->head = newNode; //改变链表头作为新生成的结点。
	}
	else //从链表头开始,执行n-1次循环
	{
		ListNode* current=list->head; //定义一个迭代器寻找结点

		for (int j = 0; j < i - 1; j++)
		{
			current = current->next;//找到插入结点的前驱结点;
		}
		newNode->next=current->next;//把新结点的后记变成cur的后继结点
		current->next = newNode;//把cur的后继变为新生成的结点。
	}
	list->len++;
}

4.1:头插法图解:

 4.2、else:尾插法图解:

5、删除节点:

//删除结点
void Delete_LinkList(LinkedList* list, int i)
{
	if (i < 0 || i >= list->len)
	{
		printf("删除失败");
		return;
	}
	if (i == 0) //删除链表的头节点
	{
		ListNode* temp = list->head->next;//把链表的头节点的后续结点进行一个缓存
		free(list->head);	//释放要删除的结点
		list->head = temp; //把头节点指向第下一个结点
	}
	else	//表示删除的不是头节点
	{
		ListNode* current = list->head; //定义一个迭代器

		for (int j = 0; j < i - 1; j++)//找到需要删除节点的前驱节点
		{
			current = current->next;
		}

		ListNode* temp = current->next->next;//把要删除的后继节点存储起来
		free(current->next);//利用free把要删除的节点给释放掉
		current->next=temp;
	}
	list->len--;//长度减1
}

5.1、删除节点图解(头节点):

5.2:删除节点图解(非头节点)

6、查找元素:(通过链表的元素来查找,返回链表节点)

//通过元素来查找链表结点
ListNode* Find_element_Linked(LinkedList* list, int value)
{
	ListNode* current = list->head;//先定义一个迭代器指向头节点
	
	while (current)	//当迭代器不为空时,也就是还没有遍历完整个链表 
	{
		if (current->data == value) //找到了目标结点
 		{
			return current;
		}
		current = current->next;//往下找;
	}
	return NULL;//表示没有找到
}

7、查找元素:(通过链表的下标来进行查找,返回链表的节点)

//通过下标来寻找链表的结点
ListNode* Find_Index_Linked(LinkedList* list, int i)
{
	if (i < 0 || i >= list->len) //越界
	{
		printf("寻找错误");
		return NULL;
	}

	ListNode* current = list->head;//迭代器

	for (int j = 0; j < i; j++) //循环遍历寻找元素
	{	
		current = current->next;//往后移
	}
	return current;
}

8、更新链表的结点值:

//更新链表的元素
void Update_LInked(LinkedList* list, int i, int value)
{
	ListNode* temp = Find_Index_Linked(list, i);//直接调用通过下标来寻找链表节点的函数

	if (temp)	//如果节点存在
	{
		temp->data = value;//修改值即可
	}
}

9、遍历链表:

void Print_Linked(LinkedList* list)
{
	ListNode* current = list->head;//迭代器
	
	while (current)
	{
		printf("%d ->", current->data);
		current=current->next; //往下走
	}
	printf("NULL\n");
}

10、完整的代码实现:

至此,我们对于链表的功能已全部实现,欢迎大家勘误。下面是完整的代码实现:

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>

typedef struct  ListNode{ //创建链表单独结点
	int data; //数值域
	struct ListNode* next; //下一个结点的指针域
}ListNode;

typedef struct LinkedList { //完整的链表
	struct ListNode* head; //头结点,也就是一个单独结点
	int len; //长度
}LinkedList;

void Creat_LinkedList(LinkedList* list) //创建一个链表
{
	//把头节点置空,长度置为0
	list->head = NULL;
	list->len = 0;
}

void Destroy_LinkList(LinkedList* list) //销毁一个链表
{
	while (list->head) //当头节点不为空时
	{
		ListNode* temp = list->head; //用一个临时的结点指向此时的头节点
		list->head = list->head->next; //将指针指向头指针的下一个结点
		free(temp); //把临时变量释放,也就把此时的结点释放
	}
	list->len = 0; //链表长度归0
}

//在链表中插入一个元素,在第i个位置插入value值
void Insert_LinkList(LinkedList* list, int i, int value)
{
	if (i<0 || i>list->len) //位置越界
	{
		printf("插入失败");
		return;
	}
	//表明位置合法:1.创建结点->改变指针方向
	ListNode* newNode=(ListNode*)malloc(sizeof(ListNode));
	newNode->data = value;//把数据赋值给新创建的数值域

	if (i == 0) //表明需要在头头节点的位置插入元素(即改变头指针的指向),使用头插法
	{
		newNode->next = list->head; //新生成的结点,指向链表头
		list->head = newNode; //改变链表头作为新生成的结点。
	}
	else //从链表头开始,执行n-1次循环
	{
		ListNode* current=list->head; //定义一个迭代器寻找结点

		for (int j = 0; j < i - 1; j++)
		{
			current = current->next;//找到插入结点的前驱结点;
		}
		newNode->next=current->next;//把新结点的后记变成cur的后继结点
		current->next = newNode;//把cur的后继变为新生成的结点。
	}
	list->len++;
}

//删除结点
void Delete_LinkList(LinkedList* list, int i)
{
	if (i < 0 || i >= list->len)
	{
		printf("删除失败");
		return;
	}
	if (i == 0) //删除链表的头节点
	{
		ListNode* temp = list->head->next;//把链表的头节点的后续结点进行一个缓存
		free(list->head);	//释放要删除的结点
		list->head = temp; //把头节点指向第下一个结点
	}
	else	//表示删除的不是头节点
	{
		ListNode* current = list->head; //定义一个迭代器

		for (int j = 0; j < i - 1; j++)//找到需要删除节点的前驱节点
		{
			current = current->next;
		}

		ListNode* temp = current->next->next;//把要删除的后继节点存储起来
		free(current->next);//利用free把要删除的节点给释放掉
		current->next=temp;
	}
	list->len--;//长度减1
}

//通过元素来查找链表结点
ListNode* Find_element_Linked(LinkedList* list, int value)
{
	ListNode* current = list->head;//先定义一个迭代器指向头节点
	
	while (current)	//当迭代器不为空时,也就是还没有遍历完整个链表 
	{
		if (current->data == value) //找到了目标结点
 		{
			return current;
		}
		current = current->next;//往下找;
	}
	return NULL;//表示没有找到
}
//通过下标来寻找链表的结点
ListNode* Find_Index_Linked(LinkedList* list, int i)
{
	if (i < 0 || i >= list->len) //越界
	{
		printf("寻找错误");
		return NULL;
	}

	ListNode* current = list->head;//迭代器

	for (int j = 0; j < i; j++) //循环遍历寻找元素
	{	
		current = current->next;//往后移
	}
	return current;
}

//更新链表的元素
void Update_LInked(LinkedList* list, int i, int value)
{
	ListNode* temp = Find_Index_Linked(list, i);//直接调用通过下标来寻找链表节点的函数

	if (temp)	//如果节点存在
	{
		temp->data = value;//修改值即可
	}
}

void Print_Linked(LinkedList* list)
{
	ListNode* current = list->head;//迭代器
	
	while (current)
	{
		printf("%d ->", current->data);
		current=current->next; //往下走
	}
	printf("NULL\n");
}



int main()
{
	LinkedList list;//定义一个链表

	Creat_LinkedList(&list);//初始化链表

	Insert_LinkList(&list, 0, 10);//插入值 
	Insert_LinkList(&list, 1, 20);
	Insert_LinkList(&list, 2, 30);
	Insert_LinkList(&list, 3, 40);

	printf("Original List:");//检验打印
	Print_Linked(&list);

	Delete_LinkList(&list, 2);
	Update_LInked(&list, 1, 100);
	printf("Change1 List:");
	Print_Linked(&list);

	ListNode* found = Find_element_Linked(&list, 30);
	if (!found)
	{
		printf("此节点不存在\n");
	}

	system("pause");
	return 0;
 }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值