19.1 C语言链表 -- 简单

链表节点(Node)

在C语言中,链表节点(Node)是构建链表数据结构的基本单元。每个结点包含两个核心部分:数据域合指针域

静态链表

静态链表的特定主要创建在栈区

复制代码
#include "stdio.h"
#include "linked_list.h"

struct linkNode {
	int num;
	struct linkNode* next;
};

//静态链表
void static_list_table() {
	struct linkNode node01 = {10 , NULL};
	struct linkNode node02 = {20 , NULL};
	struct linkNode node03 = {30 , NULL};
	struct linkNode node04 = {40 , NULL};
	struct linkNode node05 = {50 , NULL};

	//静态链表建立关系
	node01.next = &node02;
	node02.next = &node03;
	node03.next = &node04;
	node04.next = &node05;

	//打印数据
	struct linkNode* curruntNode = &node01;
	while (curruntNode != NULL) {
		printf("%d\n", curruntNode->num);

		//移动下一个位置
		curruntNode = curruntNode->next;
	}
}

void test_01_mian() {
	static_list_table();
}

动态链表

动态链表的特定主要创建在堆区

复制代码
#include "stdio.h"
#include "linked_list.h"

struct linkNode {
	int num;
	struct linkNode* next;
};

//动态链表
void dynamic_list_table() {
	
	//堆区创建节点
	struct linkNode* node01 = malloc(sizeof(struct linkNode));
	struct linkNode* node02 = malloc(sizeof(struct linkNode));
	struct linkNode* node03 = malloc(sizeof(struct linkNode));
	struct linkNode* node04 = malloc(sizeof(struct linkNode));
	struct linkNode* node05 = malloc(sizeof(struct linkNode));

	//数据赋值
	node01->num = 10;
	node02->num = 20;
	node03->num = 30;
	node04->num = 40;
	node05->num = 50;

	//建立关系
	node01->next = node02;
	node02->next = node03;
	node03->next = node04;
	node04->next = node05;

	//遍历节点
	struct linkNode* currentNode = node01;
	while (currentNode != NULL) {
		printf("%d\n",currentNode->num);
		
		//移动下一个位置
		currentNode = currentNode->next;
	}

	//释放内存
	free(node01);
	free(node02);
	free(node03);
	free(node04);
	free(node05);
}

void test_01_mian() {
	dynamic_list_table();
}

链表分类

带头和不带头列表

带头链表:就是头部创建一个头结点,接结点保持不变,起到一个标志性作用,不管后面结点如何变化,头结点始终不变

不带头链表:头结点不固定,根据实际需要更换头结点,在原来头结点中插入新节点,新节点作为头结点

链表初始化操作

复制代码
#include "stdio.h"
#include "linked_list.h"

struct linkNode{
	int num;
	struct linkNode* next;
};


//创建一个初始化结点
struct linkNode* initNode() {
	struct linkNode*  pHead = malloc(sizeof(struct linkNode));
	if (pHead == NULL) {
		printf("初始化失败,内存分配失败\n");
		return NULL;
	}

	//带头结点赋值
	pHead->next = NULL;//带头结点只维护指针域,不维护数据域

	//创建一个尾结点
	struct linkNode* pTail = pHead;

	int var = -1; 
	while (1) {
		printf("请输入num 输入-1结束运行\n");
		scanf_s("%d",&var);
		if (var == -1) {
			printf("退出运行...\n");
			break;
		}

		struct linkNode* newNode = malloc(sizeof(struct linkNode));
		newNode->num = var;
		newNode->next = NULL;
		
		//建立关系
		pTail->next = newNode;
		//更新尾结点
		pTail = newNode;
	}

	return pHead;
}


//循环打印链表
void foreach_ListNode(struct linkNode* head) {

	if (head == NULL) {
		return;
	}

	struct linkNode* currenNode = head->next;

	while (currenNode != NULL) {
		printf("%d\n", currenNode->num);

		currenNode = currenNode->next;
	}
}

void test_01_mian() {
	struct linkNode * head = initNode();
	foreach_ListNode(head);
}

链表插入操作

复制代码
#include "stdio.h"
#include "linked_list.h"


struct linkNode {
	int num;
	struct linkNode* next;
};

//创建一个初始化结点
struct linkNode* initNode() {
	struct linkNode*  pHead = malloc(sizeof(struct linkNode));
	if (pHead == NULL) {
		printf("初始化失败,内存分配失败\n");
		return NULL;
	}

	//带头结点赋值
	pHead->next = NULL;//带头结点只维护指针域,不维护数据域

	//创建一个尾结点
	struct linkNode* pTail = pHead;

	int var = -1; 
	while (1) {
		printf("请输入num 输入-1结束运行\n");
		scanf_s("%d",&var);
		if (var == -1) {
			printf("退出运行...\n");
			break;
		}

		struct linkNode* newNode = malloc(sizeof(struct linkNode));
		newNode->num = var;
		newNode->next = NULL;
		
		//建立关系
		pTail->next = newNode;
		//更新尾结点
		pTail = newNode;
	}

	return pHead;
}


//循环打印链表
void foreach_ListNode(struct linkNode* head) {

	if (head == NULL) {
		printf("循环打印失败传输指针为空\n");
		return;
	}

	struct linkNode* currenNode = head->next;

	while (currenNode != NULL) {
		printf("%d\n", currenNode->num);

		currenNode = currenNode->next;
	}
}

/*
* 插入链表
* 逻辑,首先找到原始数据,前后插入,需要记录上一个节点的记录
*/
void insert_list_node(struct linkNode* head,int oldNum,int newNum) {
	if (head == NULL) {
		printf("插入失败传输指针为空\n");
		return;
	}

	struct linkNode* pCurrent = head->next;
	struct linkNode* pPer = head;

	while (pCurrent != NULL) {

		//匹配数据
		if (pCurrent->num == oldNum) {
			break;
		}

		//如果没有比配需要建立关系
		pPer = pCurrent;
		pCurrent = pCurrent->next;
	}

	//新建一个节点
	struct linkNode * newNode = malloc(sizeof(struct linkNode));
	newNode->num = newNum;
	newNode->next = NULL;
	
	//建立关系
	newNode->next = pCurrent;
	pPer->next = newNode;

}

void test_02_mian() {

	//初始化节点
	struct linkNode * head = initNode();
	//打印节点数据
	foreach_ListNode(head);

	//往前插入
	insert_list_node(head, 10, 100);
	insert_list_node(head, 20, 200);
	insert_list_node(head, 30, 300);
	foreach_ListNode(head);
}

清空和销毁链表

复制代码
#include "stdio.h"
#include "linked_list.h"


struct linkNode {
	int num;
	struct linkNode* next;
};

//创建一个初始化结点
struct linkNode* initNode() {
	struct linkNode*  pHead = malloc(sizeof(struct linkNode));
	if (pHead == NULL) {
		printf("初始化失败,内存分配失败\n");
		return NULL;
	}

	//带头结点赋值
	pHead->next = NULL;//带头结点只维护指针域,不维护数据域

	//创建一个尾结点
	struct linkNode* pTail = pHead;

	int var = -1; 
	while (1) {
		printf("请输入num 输入-1结束运行\n");
		scanf_s("%d",&var);
		if (var == -1) {
			printf("退出运行...\n");
			break;
		}

		struct linkNode* newNode = malloc(sizeof(struct linkNode));
		newNode->num = var;
		newNode->next = NULL;
		
		//建立关系
		pTail->next = newNode;
		//更新尾结点
		pTail = newNode;
	}

	return pHead;
}


//循环打印链表
void foreach_ListNode(struct linkNode* head) {

	if (head == NULL) {
		printf("循环打印失败传输指针为空\n");
		return;
	}

	struct linkNode* currenNode = head->next;

	while (currenNode != NULL) {
		printf("%d\n", currenNode->num);

		currenNode = currenNode->next;
	}
}

/*
* 插入链表
* 逻辑,首先找到原始数据,前后插入,需要记录上一个节点的记录
*/
void insert_list_node(struct linkNode* head,int oldNum,int newNum) {
	if (head == NULL) {
		printf("插入失败传输指针为空\n");
		return;
	}

	struct linkNode* pCurrent = head->next;
	struct linkNode* pPer = head;

	while (pCurrent != NULL) {

		//匹配数据
		if (pCurrent->num == oldNum) {
			break;
		}

		//如果没有比配需要建立关系
		pPer = pCurrent;
		pCurrent = pCurrent->next;
	}

	//新建一个节点
	struct linkNode * newNode = malloc(sizeof(struct linkNode));
	newNode->num = newNum;
	newNode->next = NULL;
	
	//建立关系
	newNode->next = pCurrent;
	pPer->next = newNode;

}

/*
* 删除链表中节点
*/
void delete_list_node(struct linkNode * head,int num) {
	if (head == NULL) {
		printf("删除失败节点为空\n");
		return;
	}

	struct linkNode* pCurrent = head;
	struct linkNode* pPrev = pCurrent;

	//循环遍历
	while (pCurrent != NULL) {
		if (pCurrent->num == num) {
			break;
		}
		pPrev = pCurrent;
		pCurrent = pCurrent->next;
	}

	//判断一下是否有对应数据节点
	if (pCurrent == NULL) {
		printf("没有删除的结点\n");
		return;
	}

	//删除节点建立关系
	pPrev->next = pCurrent->next;

	//删除节点
	free(pCurrent);
	pCurrent = NULL;

}

/*
* 清空节点
* 清除后还可以往后,插入结点,链表还是可用的
*/
void clean_linkNode(struct linkNode *head) {
	if (head == NULL) {
		printf("清空链表失败\n");
		return;
	}

	struct linkNode* pCurrent = head->next;
	while (pCurrent != NULL) {
		struct linkNode* pNext = pCurrent->next;

		//释放当前节点
		free(pCurrent);

		//把下一个节点赋值给当前节点。这一步是方便下次循环利用
		pCurrent = pNext;
	}

	//头节点设置空
	head->next = NULL;
}

/*
* 销毁节点
*/
void destroy_linkNode(struct linkNode* head) {
	if (head == NULL) {
		printf("销毁链表失败\n");
		return;
	}
	//先清空链表
	clean_linkNode(head);

	//在释放头节点
	free(head);
	head = NULL;
}

void test_02_mian() {

	//初始化节点
	printf("=====================start===========================\n");
	printf("=====================初始化===========================\n");
	struct linkNode * head = initNode();
	//打印节点数据
	foreach_ListNode(head);

	printf("=====================往前插入===========================\n");
	//往前插入
	insert_list_node(head, 10, 100);
	insert_list_node(head, 20, 200);
	insert_list_node(head, 30, 300);
	foreach_ListNode(head);

	printf("======================删除节点==========================\n");
	//删除节点
	delete_list_node(head, 10);
	delete_list_node(head, 300);
	foreach_ListNode(head);

	printf("======================清除节点==========================\n");
	//清除节点
	clean_linkNode(head);
	foreach_ListNode(head);
	printf("=======================清除节点后再插入=========================\n");
	insert_list_node(head, 300, 3000);
	insert_list_node(head, 400, 4000);
	foreach_ListNode(head);

	printf("=======================end=========================\n");

}
相关推荐
怎么没有名字注册了啊2 小时前
解决qt制作软件.app迁移问题(发布)Mac
开发语言·qt
llm大模型算法工程师weng2 小时前
Java高并发架构设计:从理论到实战的全链路解决方案
java·开发语言
gihigo19982 小时前
MATLAB地震面波数值模拟方案
开发语言·matlab
CeshirenTester2 小时前
Claude Code 不只是会写代码:这 10 个 Skills,才是效率分水岭
android·开发语言·kotlin
并不喜欢吃鱼2 小时前
从零开始C++----四.vector的使用与底层实现
开发语言·c++
沐雪轻挽萤2 小时前
17. C++17新特性-并行算法 (Parallel Algorithms)
java·开发语言·c++
墨澜逸客2 小时前
华胥祭坛志---文/墨澜逸客
开发语言·深度学习·学习·百度·php·学习方法·新浪微博
覆东流2 小时前
第3天:Python print深入与格式化输出
开发语言·后端·python
加号33 小时前
C# 基于MD5实现密码加密功能,附源码
开发语言·c#·密码加密