Linux笔记 --- 传统链表
目录
链表
单向链表
单向循环链表
双向链表
设计表
初始化
在auchor后插入节点,
在auchor前插入节点
删除节点
传统链表
通过使用链表我们可以将一个数组中的数据分开到不同位置存放并使用指针指向他们,使之逻辑相连,解决了顺序存储所需要一大块内存的问题,同时删除插入和扩展节点非常便利。为此,我们需要在定义链表时预留一个指针指向其他数据存放的地址,使得节点逻辑连贯,根据不同情况我们可以设置单向或者双向指针
单向链表
单向链表指的就是节点中只包含一个指针,该指针用来指向相邻节点。对链表的操作,最基本的就是初始化空链表、创建新节点、插入节点、删除节点、移动节点、查找节点和遍历链表,下面先给出节点的设计代码,然后针对以上所述的操作各个击破。
第一,设计节点
节点的设计非常重要,关乎后续对链表各种操作,而单向(循环)链表节点的设计就非常简单,假设我们要处理的数据类型叫datatype,我们只需要在节点中增加一个指向本节点类型的指针即可:
typedef struct node
{int data;struct node *next;
}listnode,*singly_list;
第二,初始化
空链表分为有头节点的空链表和不带头节点的空链表,在不带有头节点的空链表情况下插入时要先判断头节点是否为空,因此我们一般更倾向于创建带有头节点的空链表,创建函数如下:
singly_list init_list (void)
{singly_list mylist = malloc(sizeof(listnode));if(mylist != NULL){mylist->next = NULL;}return mylist;
}
第三,插入节点
链表最大的又是就是插入删除非常简单,单向链表中插入节点只需要修改两个指针,将新节点指向插入位置后一个节点,将前一个节点指向新节点
void insert_node(singly_list p,singly_list new)
{if(p == NULL || new == NULL)return;new->next = p->next;p->next = new;
}
第四,删除节点
对于单向链表来说,没有指向前置节点的指针,因此我们要先创建一个指针寻找到前置指针,然后再进行删除
bool remove_node(singly_list mylist,singly_list delete)
{if(is_empty(mylist))return false;singly_list p = mylist;while (p != NULL && p->next != delete){p = p->next;}if(p == NULL)return false;p->next = delete->next;delete->next = NULL;return true;
}
第五,移动节点
因为我们在前面已经将插入和删除封装进了函数,因此我们移动节点将会很简便
void move_node(singly_list mylist , singly_list p , singly_list anchor)
{if(mylist == NULL || p == NULL || anchor == NULL)return ;remove_node(mylist,p);insert_node(anchor,p);
}
第六,根据内容查找指针
singly_list remove_node(singly_list mylist,int data)
{if(is_empty(mylist))return NULL;singly_list p;// p = mylist;// while (p != NULL && p->next->data != data)// {// p = p->next;// }// if(p == NULL)// return false;// p = p->next;for(p = mylist->next ; p != NULL ; p = p->next){if (p->data == data){break;}}return p;
}
用了两种方法,逻辑相同酌情使用
单向循环链表
所谓单线循环链表就是单向链表中最后一个节点指向头节点,初始化方式如下
linklist init_list (void)
{linklist head = malloc(sizeof(listnode));head->next = head;return head;
}
删除节点,对于单向循环链表来说不是必须指定头节点,可以直接从需要删除的节点开始轮询
void remove_node(linklist delete)
{linklist temp = delete;while (temp->next != delete){temp = temp->next;}temp->next = delete->next;delete->next = NULL;
}
移动节点,相比于单链表循环链表不需要从头节点开始轮询所以可以减少参数
void move_node(linklist p , linklist anchor)
{if(p == NULL || anchor == NULL)return ;remove_node(p);insert_node(anchor,p);
}
查找节点,查找节点方面,循环列表跟单链表的区别就是判断查找结束的条件不同
linklist find_node(linklist mylist,int data)
{if(is_empty(mylist))return NULL;linklist p;for(p = mylist->next ; p != mylist ; p = p->next){if (p->data == data){break;}}return p == mylist ? NULL : p;
}
双向链表
设计表
相较于单链表来说双向链表多了一个指向前一个节点的指针
typedef struct node
{int data;struct node *next;struct node *prev;
}listnode,*double_list;
初始化
比单链表多一个指向自己的指针
double_list init_list (void)
{double_list mylist = malloc(sizeof(listnode));if(mylist != NULL){mylist->prev = mylist->next = NULL;}return mylist;
}
在auchor后插入节点,
在双向链表中需要操作四个指针
void insert_next(double_list new,double_list auchor)
{if(new == NULL||auchor == NULL);return;new->prev = auchor;new->next = auchor->next;auchor->next = new;new->next->prev = new;
}
在auchor前插入节点
void insert_prev(double_list new,double_list auchor)
{if(new == NULL||auchor == NULL);return;new->prev = auchor->prev;new->next = auchor;new->prev->next = new;auchor->prev = new;
}
删除节点
void remove_node(double_list delete)
{if(delete == NULL);return;delete->prev->next = delete->next;delete->next->prev = delete->prev;delete->next = NULL;delete->prev = NULL;
}
移动节点
分为移动到目标前后
void move_next(double_list p,double_list auchor)
{remove_node(p);insert_next(p,auchor);
}void move_prev(double_list p,double_list auchor)
{remove_node(p);insert_prev(p,auchor);
}
查找节点
double_list find_node(double_list mylist,int data)
{if(is_empty(mylist))return NULL;double_list p;for(p = mylist->next ; p != mylist ; p = p->next){if (p->data == data){break;}}return p == mylist ? NULL : p;
}
传统链表的坏处
传统的双向循环链表概念简单,操作方便,但存在有致命的缺陷,用一句话来概括就是:每一条链表都是特殊的,不具有通用性。换句话说,对于每一种不同的数据,所构建出来的传统链表都是跟这些数据相关的,所有的链表操作函数也都是数据相关的,换一种数据节点,则所有的操作函数都需要一一重写编写,这种缺陷对于一个具有成千上万种数据节点的工程来说是灾难性的,是不可接受的。
简而言之,对于每个不同类型的节点我们没办法使用同一套函数操作他们,这在大型工程中很不方便
究其原因,传统节点不仅包含了表达链表逻辑的指针,更包含了某一个具体类型的数据,而指针无法跟数据分开,于是出现了这样的问题
相关文章:

Linux笔记 --- 传统链表
目录 链表 单向链表 单向循环链表 双向链表 设计表 初始化 在auchor后插入节点, 在auchor前插入节点 删除节点 传统链表 通过使用链表我们可以将一个数组中的数据分开到不同位置存放并使用指针指向他们,使之逻辑相连,解决了顺序存储所需要…...

C语言的编译(预处理操作)+链接
目录 翻译环境和执行环境 预定义符号 #define定义标识符 续行符\ #define定义宏 再说一下,#define其实就是替换 #和## 宏和函数的对比 命名约定 #undef 命令行定义 条件编译 文件包含 避免头文件重复引用,否则会增加代码长度 翻译环境和执行环境 在C中存…...

FFmpeg实战 - 解复用与解码
大纲目录 文章目录 前置知识音视频基础概念解复用、解码的流程分析FFMPEG有8个常用库 常见音视频格式的介绍aac格式介绍(ADTS)h264格式分析FLV和MP4格式介绍 FFmpeg解码解封装实战数据包和数据帧(AVPacket/AVFrame)AVPacket/AVFra…...

8.5作业
1.思维导图 2.提示并输入一个字符串,统计该字符中大写、小写字母个数、数字个数、空格个数以及其他字符个数,要求使用C风格字符串完成 #include <iostream>using namespace std;int main() {string str;cout << "请输入一个字符串&quo…...
【问题】C++:有哪些类型的智能指针,区别?
智能指针是一种在 C 中管理动态分配内存的工具,可以帮助避免内存泄漏和提高程序的安全性。在 C11 标准引入之后,C 提供了三种主要类型的智能指针,它们分别是 std::unique_ptr、std::shared_ptr 和 std::weak_ptr。这些智能指针有不同的所有权…...
Go-反射
概念 在Go语言中,反射(reflection)是指在运行时检查程序的结构、变量和接口的机制。可以通过反射获取和修改变量的值、获取变量的类型信息、调用方法等操作。 反射主要由reflect包提供,它定义了两个重要的类型:Type和…...

【深度学习】DeepSpeed,ZeRO 数据并行的三个阶段是什么?
文章目录 ZeRO实验实验设置DeepSpeed ZeRO Stage-2 实验性能比较进一步优化DeepSpeed ZeRO Stage-3 和 CPU 卸载结论ZeRO ZeRO(Zero Redundancy Optimizer)是一种用于分布式训练的大规模深度学习模型的优化技术。它通过分片模型状态(参数、梯度和优化器状态)来消除数据并行…...
代码随想录算法训练营第三十六天 | 1049. 最后一块石头的重量 II、494. 目标和、474.一和零
一、1049. 最后一块石头的重量 II 题目链接:1049. 最后一块石头的重量 II - 力扣(LeetCode) 文章讲解:代码随想录 (programmercarl.com)——1049. 最后一块石头的重量 II 视频讲解:动态规划之背包问题,这个…...
Pandas行列变换指南:数据重塑的艺术
数据分析中,数据的形态至关重要。pandas库提供了一系列工具,让我们能够轻松地重塑数据。以下是一些常见的pandas行列变换方法,每种方法都配有完整的代码示例。 环境准备 首先,确保你的环境中安装了pandas和numpy库: …...

1.MySQL面试题之innodb如何解决幻读
1. 写在前面 在数据库系统中,幻读(Phantom Read)是指在一个事务中,两次读取同一范围的数据集时,由于其他事务的插入操作,导致第二次读取结果集发生变化的问题。InnoDB 作为 MySQL 的一个存储引擎ÿ…...
Nginx中$http_host、$host、$proxy_host的区别
知识巩固! 网上看到这篇文章,这里转载记录一下。 简介 变量是否显示端口值是否存在 host 浏览器请求的ip,不显示端口 否 "Host:value"显示 值为a:b的时候,只显示a http_host 浏览器请求的ip和端口号 是"Host:v…...

C# Unity 面向对象补全计划 七大原则 之 里氏替换(LSP) 难度:☆☆☆ 总结:子类可以当父类用,牛马是马,骡马也是马
本文仅作学习笔记与交流,不作任何商业用途,作者能力有限,如有不足还请斧正 本系列作为七大原则和设计模式的进阶知识,看不懂没关系 请看专栏:http://t.csdnimg.cn/mIitr,尤其是关于继承的两篇文章ÿ…...

PXE批量安装操作系统
PXE批量安装操作系统 系统环境rhedhat7.9关闭vmware内的dhcp服务 kickstart自动安装脚本的制作 在rhel7系统中提供图形的kickstart制作方式 在rhel8中已经把图形的工具取消,并添加到rhn网络中 在rhel8中如果无法通过rhn网络制作kickstart,可以使用模板…...
float32转float16、snorm/sunorm8/16 学习及实现
1、基础 彻底搞懂float16与float32的计算方式-CSDN博客 例1:float32 0x3fd00000 32b0 011_1111 _1 101_0000_0000_0000_0000_0000 sign0 exp8b0111_1111 h7f d127 >0ffset 127-127 0 mantissa b101_0000_0000_0000_0000_0000(补1,1.1010…...

小型养猫空气净化器怎么选?小型养猫空气净化器产品评测
家养四只猫猫,对于各个角落的猫毛,感觉家里已经被猫毛占领了。感受一下40度高温的养猫人,给掉毛怪疏毛浮毛飘飘,逃不过的饮水机,各个角落,多猫拉臭传来的异味。 一、养猫带来的麻烦 掉毛:每到换…...

数学建模--二分法
目录 二分法的基本原理 应用实例 求解方程根 查找有序数组中的元素 注意事项 Python代码示例 编辑 延伸 二分法在数学建模中的具体应用案例有哪些? 如何选择二分法的初始区间以确保收敛速度和精度? 在使用二分法求解方程时,如何…...

如何使用 Puppeteer 绕过 Akamai
摘要: 本文深入探讨了在面对Akamai强大防护下的网页抓取挑战时,如何运用Puppeteer这一强大的Node.js库,通过模拟真实用户行为、动态请求处理等策略,高效且隐蔽地收集数据。我们将一步步揭开Puppeteer绕过Akamai的神秘面纱&#x…...
【硬件知识】车规级开发等级——AEQ-100和ISO26262标准
文章目录 一、定义二、区别1.应用场景2.使用方法 总结 一、定义 AEQ-100(Automotive Electronics Council Q100)是一个由汽车电子委员会(AEC)制定的标准,主要用于保证汽车电子元件的可靠性。它是一个关于汽车级半导体…...
Qt | QStackedBarSeries(堆叠条形图)+QPercentBarSeries(堆叠百分比条形图)
点击上方"蓝字"关注我们 01、QBarSet 1. 首先,需要创建一个名为QBarSet的类。 2. 在QBarSet类中,定义所需的属性和方法。 3. 属性可能包括条形的名称、颜色、值等。 4. 方法可能包括添加条形、删除条形、计算总和等。 5. 确保QBarSet类能够与QBar类协同工作,…...

C++——多态经典案例(一)组装电脑
案例:小明打算买两台组装电脑,假设电脑零部件包括CPU、GPU和内存组成。 一台电脑使用intel的CPU、GPU和内存条 一台电脑使用Huawei的CPU、GPU和Intel的内存条 分析:使用多态进行实现 将CPU、GPU和内存条定义为抽象类,内部分别定义…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...

家政维修平台实战20:权限设计
目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系,主要是分成几个表,用户表我们是记录用户的基础信息,包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题,不同的角色…...

el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...

零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...

图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...

C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...