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

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

相关推荐
Engineer邓祥浩2 小时前
知识点1 时间复杂度、空间复杂度
java·数据结构·算法
博界IT精灵2 小时前
森林和二叉树的转换(哈喜老师)
数据结构
代码中介商2 小时前
C语言进程管理与内存管理深度解析
c语言·开发语言
Severus_black2 小时前
算法题C——用队列实现栈/用栈实现队列
c语言·数据结构·算法·链表
神明不懂浪漫3 小时前
【第一章】数据结构——预备知识
开发语言·数据结构·经验分享·笔记
承渊政道3 小时前
【递归、搜索与回溯算法】(掌握记忆化搜索的核心套路)
数据结构·c++·算法·leetcode·macos·动态规划·宽度优先
叶子野格3 小时前
《C语言学习:数组》11
c语言·开发语言·c++·学习·visual studio
Little At Air3 小时前
C++priority_queue模拟实现
开发语言·数据结构·c++
程序员zgh3 小时前
C++ decltype 关键字 详解
c语言·开发语言·c++