【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,双向链表的关键操作就介绍到这里。希望大家通过今天的学习,能轻松掌握它!

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

相关推荐
学生小羊2 分钟前
C++ 初阶 学习博客
c语言·c++·c++与c语言的区别·c++基础学习
雨落在了我的手上6 分钟前
Java数据结构(十五):哈希表
数据结构
无忧.芙桃1 小时前
数据结构之排序算法(中):冒泡排序与快速排序,从相邻交换到工程级优化
c语言·c++·排序算法
Hhy_11071 小时前
《C++深度解构04》类和对象(下)——类型转换、static、友元与编译器优化
c语言·c++·学习·类和对象·visual studio
有点。10 小时前
C++03阶段练习(练习题)
数据结构·算法·图论
free-elcmacom12 小时前
C语言字符指针与字符串字面量——从一道“剑指 Offer”笔试题说起
c语言·visual studio
午彦琳15 小时前
2026.9.17
数据结构·算法·leetcode
free-elcmacom17 小时前
C语言指针进阶——指针数组模拟二维数组,以及二级指针到底怎么理解
c语言·visual studio code
山下梅子酒22518 小时前
洛谷-入门-B2049
c语言
All for pursuit.19 小时前
【链表-9】146.LRU缓存
数据结构·c++·算法·leetcode