
链表节点(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");
}