【C语言数据结构】之解锁双向链表(指定位置插入、删除节点、查找、销毁链表等操作)

"Hello大家好,欢迎来到**【01二进制代码漫游日记】!**

今天我们的主题是C语言数据结构中的双向链表。我们将快速解锁它的核心操作:指定位置插入、删除节点、查找以及销毁链表。话不多说,直接上代码,一起玩转双向链表!"

"在正式动手写代码之前,我们先来认识一下今天项目的'三剑客'。一个结构清晰的项目,能让我们的思路事半功倍。我们一共准备了三个文件,它们各司其职,协同工作。"

一、文件定义及作用

1.1.List.h文件及作用

首先登场的是我们的'总设计师'------List.h头文件。它的作用非常关键,负责定义双向链表的'蓝图',也就是我们的节点结构体,同时也会声明所有函数的接口。其他文件想要和链表打交道,都得先包含它。

1.2.4-21.c文件及作用

接下来是我们的'实干家'------4-21.c实现文件。所有函数的具体逻辑和'硬功夫',比如插入、删除节点的具体代码,都会写在这里。它是整个项目的核心。

1.3.test.h文件及作用

最后是我们的'体验官'------test.h测试文件。它是程序的入口,也就是main函数所在的地方。我们会在这里演示如何使用前面定义好的所有功能,来验证我们的链表是否工作正常。

好了,认识了这三位'伙伴',"项目结构清晰了,万事俱备,只欠代码!那我们该从哪里下手呢?对于一个数据结构来说,'查找'是所有操作的基石。只有先学会了如何精准定位,我们才能对它进行后续的增删改。所以,我们的第一站,就从这里开始。

二、查找及其实现方法

2.1.List.h部分

代码如下:

#pragma once

#include<stdio.h>

#include<stdlib.h>

#include<assert.h>

typedef int LTDataType;

typedef struct LTNode {

LTDataType data;

struct LTNode* prev;

struct LTNode* next;

}LTNode;

//申请节点

LTNode* LTBuyNode(LTDataType x);

void LTInit(LTNode** pphead);

void LTPushBack(LTNode* phead, LTDataType x);

void LTPrint(LTNode* phead);

void LTPushFront(LTNode* phead, LTDataType x);

void LTPopBack(LTNode* phead);

//头删

void LTPopFront(LTNode* phead);

//查找

LTNode* LTFind(LTNode* phead, LTDataType x);

2.2.4-21.c部分

查找代码如下:

//查找

LTNode* LTFind(LTNode* phead, LTDataType x) {

assert(phead);

LTNode* pcur = phead->next;

while (pcur != phead) {

if (pcur->data == x) {

return pcur;

}

pcur = pcur->next;

}

return NULL;

}

2.3.test.c部分

测试代码如下:

//查找

LTNode*pos=LTFind(plist, 1);

if (pos != NULL) {

printf("找到了,是%d\n",pos->data);

}

else {

printf("没有找到,请重新输入:");

}

}

测试结果如下:

"查找是为了定位,而定位往往是为了后续的修改做准备。搞定了'在哪里'的问题,接下来我们看看'怎么做'------如何在找到的这个位置之后,插入新的节点

三、在指定位置之后插入数据

3.1.List.h部分

代码如下:

//在指定位置之后插入新结点

void LTInsert(LTNode* phead, LTDataType x);

3.2.4-21.c部分

代码如下:

//在指定位置之后插入新结点

void LTInsert(LTNode* pos, LTDataType x) {

assert(pos);

LTNode* newnode = LTBuyNode(x);

newnode->next = pos->next;

newnode->prev = pos;

pos->next->prev = newnode;

pos->next = newnode;

}

3.3.test.c部分

代码如下:

//在指定位置之后插入新结点

LTNode* pos2 = LTFind(plist, 2);

if (pos2) {

LTInsert(pos2, 8);

}

LTNode* pos4 = LTFind(plist, 9);

if (pos4) {

LTInsert(pos4, 9);

}

LTPrint(plist);

测试结果如下:

"在动态的数据世界里,有增就有减。我们刚刚攻克了'在指定位置之后插入数据'的难题,让链表变得灵活多变。但光会'增'还不够,当某个节点的数据过时或无效时,我们需要一种机制来'修剪'它。接下来,我们就来探讨如何删除指定位置的节点。"

四、删除pos(指定位置)节点

4.1.List.h部分

代码如下:

#pragma once

#include<stdio.h>

#include<stdlib.h>

#include<assert.h>

typedef int LTDataType;

typedef struct LTNode {

LTDataType data;

struct LTNode* prev;

struct LTNode* next;

}LTNode;

//申请节点

LTNode* LTBuyNode(LTDataType x);

void LTInit(LTNode** pphead);

void LTPushBack(LTNode* phead, LTDataType x);

void LTPrint(LTNode* phead);

void LTPushFront(LTNode* phead, LTDataType x);

void LTPopBack(LTNode* phead);

//头删

void LTPopFront(LTNode* phead);

//查找

LTNode* LTFind(LTNode* phead, LTDataType x);

//在指定位置之后插入新结点

void LTInsert(LTNode* pos, LTDataType x);
//删除指定位置结点
void LTErase(LTNode* pos);

4.2. 4-21.c部分

代码如下:

//删除指定位置结点

void LTErase(LTNode* pos) {

assert(pos);

pos->next->prev = pos->prev;

pos->prev->next = pos->next; \

free(pos);

pos = NULL;

}

4.3.test.c部分

代码如下:

//删除指定位置结点

LTNode* pos = LTFind(plist, 9);

if (pos != NULL) {

LTErase(pos);

}

LTPrint(plist);

测试结果如下:

"我们刚刚学会了如何精准地删除单个节点,就像处理掉一个废弃的零件。但在程序的世界里,当我们彻底完成一个任务,不再需要整个数据结构时,就不能只删除某一个节点了。我们需要一种'大扫除'式的操作,一次性释放所有节点,将内存归还给系统。这不仅是一种操作,更是一种编程的责任。下面,让我们来完成链表的销毁。"

五、销毁链表

5.1List.h部分

代码如下:

//销毁链表

void LTDestroy(LTNode* phead);

5.2. 4-21.c部分

代码如下:

//销毁链表

void LTDestroy(LTNode* phead) {

assert(phead);

LTNode* pcur = phead->next;

while (pcur != phead) {

LTNode* next = pcur->next;

free(pcur);

pcur = next;

}

free(phead);

phead = NULL;

}

5.3.test.c部分

代码如下:

LTPrint(plist);

//销毁链表

LTDestroy(plist);

LTPrint(plist);

plist = NULL;

}

"OK,双向链表的关键操作就介绍到这里。希望大家通过今天的学习,能轻松掌握它!

如果觉得有用**,别忘了关注我,**获取更多编程技巧和实战经验。你的支持是我更新的动力!我们下期见!"

相关推荐
YangWeiminPHD14 分钟前
金水32051编译器下的AI8051U单片机入门:从点亮LED到“你好,世界,我来了!”
c语言·汇编·51单片机·编译器
2301_7890156226 分钟前
Linux:基础指令(二)
linux·运维·服务器·c语言·开发语言·c++·算法
AI机器学习算法3 小时前
机器学习基础知识
数据结构·人工智能·python·深度学习·算法·机器学习·ai学习路线
坚果派·白晓明9 小时前
【鸿蒙PC三方库移植适配框架解读系列】第八篇:扩展lycium框架使其满足rust三方库适配
c语言·开发语言·华为·rust·harmonyos·鸿蒙
刀法如飞10 小时前
Ontology本体论是什么数据结构?Palantir 技术原理介绍
数据结构·人工智能·ai编程·图论
平行侠11 小时前
024多精度大整数 - 突破硬件精度限制的任意精度运算
数据结构·算法
谙弆悕博士11 小时前
快速学C语言——第16章:预处理
c语言·开发语言·chrome·笔记·创业创新·预处理·业界资讯
matlabgoodboy11 小时前
软件开发定制小程序APP帮代做java代码代编写C语言设计python编程
java·c语言·小程序
洛水水12 小时前
【力扣100题】32.将有序数组转换为二叉搜索树
数据结构·算法·leetcode
handler0112 小时前
UDP协议与网络通信知识点
c语言·网络·c++·笔记·网络协议·udp