链表(linked list)

双向链表(Double Linked List) 虽然单向链表能够100%解决逻辑关系为“一对一”数据的存储问题,但在解决那些需要大量查找前趋节点的问题是,单向链表无疑是不能用了,因为单向链表适合“从前往后”查找,并不适合“从后往前”查找。如果要提高链表的查找效率,那双向链表(双链表)无疑是首选。双向链表字面上的意思是“双向”的链表,如图1所示。图1 - 双向链表示意图双向指各个节点之间的逻辑关系是双向的,该链表通常只有一个头节点。...... 阅读详情

链表的特点

  • 根据线性表元素多少,长度可变化。
  • 动态申请内存空间:元素删除或插入时,对应申请新的存储空间或释放原来占有的存储空间。
  • 使用指针来链接各个结点,按照线性表的前驱关系将结点连接起来,结点之间内存地址不必相邻。
  • 链表的访问:不能像数组那样根据下标直接访问某一个结点i,而需要从头结点开始,沿着link指针一个一个地计数(遍历),才能找到。
  • 通常有一个first指针变量和一个last指针遍历,用来存储头结点地址和末尾结点的地址(便于快速在链表末尾添加结点)。

结点数据结构

单链表结点的数据结构通常分为两部分:数据和指向后继结点的指针。

struct ListNode {
    ELEM data;
    ListNode * link;
};

ListNode *first, *last;
空链表的表示:

为了表示空链表,引入一个特殊的“首结点”,该节点中data的值被忽略,该节点不被看做列表中的实际元素,只是为了方便空链表操作和表头操作。当链表为空时,first和last均指向首结点,如下:

ListNode * headNode = new ListNode;
first =  headNode;
last = headNode;

相关算法

查找结点

查找位置为i的结点。

ListNode * find(const int i) {
    // 返回“首结点”,
    if (-1 == i) {
        return first;
    }
    // 指向第一个结点;
    ListNode * p = first->link;
    int j=0;
    // 遍历到链表末尾或j==i时停止。
    while(p != NULL && j<i) {
        p = p->link;
        j++;
    }
    // 当链表结点数量小于i时,返回NULL
    return p; 
}
新增结点

关键点:

  • 找到前序结点,注意前序结点为NULL的情况;
  • 先将新增结点的data和link设置好,新增结点的link指向前序结点的link;
    再将其前序结点的link指向新增结点。
  • 注意要考虑到新增结点在链首、中、尾这三种情况的处理,插入到链表末尾时,last指针指向该新增结点。
ListNode * insert(ELEM value, int i) {
    ListNode * preNode;
    // 查找到前序结点,因为特殊“首结点”的存在,使i==0的情况不用特殊处理。
    preNode = find(i - 1);
    if (NULL == preNode) {
        return NULL;
    }
    ListNode * newNode;
    newNode = new ListNode;
    newNode->link = preNode->link;
    newNode->data = value;
    preNode->link = newNode;
    // 处理插入到链表尾部的情况
    if (NULL == newNode->link) {
        last = newNode;
    }
    return newNode;
}
删除结点

删除某一个结点的后续结点。
关键点:

  • 在真正删除节点之前,安排好它的“后事”:将其前序结点的link指向待删除结点的link;
void removeAfter(ListNode * preNode) {
    // 暂存待删除结点
    ListNode * delLink = preNode->link;
    if (delLink != NULL) {
        preNode->link = delLink->link;
        delete delLink;
    }
}
链表长度
int length() {
    ListNode * curNode = first->link;
    int count = 0;
    while (curNode != NULL) {
        curNode = curNode->link;
        count++;
    }
    return count;
}

单链表的缺点

  • 可以方便地查询某个结点的后续结点,但不能直接查询其前驱结点。

顾名思义,它是双向列表。主要在其每个结点中增加了一个指向前驱的指针rlink,指向后续结点的指针为llink;

结点结构

struct DblListNode {
    ELEM data;
    DblListNode * preLink;
    DblListNode * nextLink;
};
DblListNode *first, *last;

空链表表示和单链表一样,使用一个特殊“首结点”,其preLink为NULL。

相关算法

新增结点

在某个结点的后面新增一个结点。

关键点:

  • 修改旧有结点的preLink或nextLink之前,一定要确定它的旧值是否已经利用完了?
DblListNode * insertAfter(ELEM value, dblListNode * node) {
    DblListNode * preNode = node->preLink;
    DblListNode * nextNode = node->nextLink;
    // 设置新增结点的各字段
    DblListNode * newNode = new DblListNode;
    newNode->data = value;
    newNode->nextLink = node->nextLink;
    newNode->preLink = node;

    node->llink->rlink = newNode;
    node->llink = newNode;
    return newNode;
}
删除结点

删除某个指定的结点。
关键点:

  • 删除前处理好“后事”:如待删除结点的前驱和后续结点是否已安排妥当?
  • 待删除结点的preLink和nextLink置为空。
void deleteNode(DblListNode * node) {
    node->preLink->nextLink = node->nextLink;
    node->nextLink->preLink = node->preLink;

    node->preLink == NULL;
    node->nextLink == NULL;
    delete node;
}

链表 vs 数组

数组

数组的优点
  • 没有使用指针,节省存储空间(因为指针需要2或4字节存储);
  • 可直接访问指定下标的元素,简洁便利,程序更易懂;
数组的缺点
  • 不可动态改变长度,必须事先确定数组长度。
  • 往数组中插入、删除某个元素时,可能需要移动O(k)个元素。
  • 需要连续的一大块存储空间,以存储所有的元素。

链表

链表的优点
  • 无需事先确定长度,可事先动态增、删元素。
  • 删除、插入元素时不需要移动O(k)个元素。
  • 结点间的存储空间不需要连续,因而可以利用一些碎片空间。

应用场合

  • 当线性表中需要经常删除、插入元素时,不使用数组,使用链表。
  • 当线性表长度不确定时,不能使用数组,使用链表,否则可能为了预留足够的空间而定义一个很大的数组,造成资源浪费。

  • 当读取操作频繁(特别是按位读取操作频繁),插入、删除操作不频繁的时候,可以使用数组。

  • 当存储的数据占的存储空间与指针占有的空间相当时(1:1),要慎重考虑使用链表是否值得。
  • 当元素内容经常更新,但删除、插入操作并不常见的时候,可以考虑使用数组作为一个“索引”,即数组中元素为一个指针,指针指向内容真正存储的地址,这样就很容易找到内容存储地址,并进行更新。
C++链表linked list(附完整源码) C++链表linked list链表linked list算法的完整源码(定义,实现,main函数测试) 链表linked list算法的完整源码(定义,实现,main函数测试) #include <iostream> #include <memory> #include <string> /** * @namespace data_structures * @brief Data Structures algorithms */ namespace data_s 阅读详情

相关推荐

C语言实现double linked list双向链表的算法(附完整源码)

C语言实现double linked list双向链表的算法C语言实现double linked list双向链表的算法完整源码(定义,实现) C语言实现double linked list双向链表的算法完整源码(定义,实现) #ifndef _DOUBLE_LINKED_LIST_H_ #define _DOUBLE_LINKED_LIST_H_ struct list_head { struct list_head * next; struct list_head * prev; };

希望我的博客,能帮上你解决学习中工作中所遇到的问题 828

Program work 6. 每个节点只含一个链接点的双向链表实现

一般我们要实现双链表的时候,每个节点都会存一个数据元,然后一个

为这个世界贡献几行代码 ~woo hoo! 622

Keil中搭建自动化单元测试框架Unity

前言:   虽然一些C++的自动化单元测试框架也能用来C语言单元测试,但那样我们编写C语言程序时需要符合C++的标准,这样有一些C的特性是无法使用的,限制C的特性使用不太好,于是找了一个全部用C实现的自动化测试框架。Unity是一个简单且直接的自动化单元测试框架,它由很少的几个文件构成。 搭建环境:   1.从github上下载最新版本的Unity源码,下载链接:https://github...

程序员的自我修炼 3898

python实现·数据结构与算法之双向链表

双向链表定义 双向链表(Double Linked List)是一种更复杂的链表,每个节点除了包含元素域,还包含两个链接:一个指向前一个节点,当此节点为第一个节点时,指向空值;另一个指向下一个节点,当此节点为最后一个节点时,指向空值。 节点示意图 表元素域elem用来存放具体的数据。 链接域prev用来存放上一个节点的位置(python中的标识) 链接域next用来存放下一个节点的位置(python中的标识) 双向链表示意图 双向链表的基本操作 is_empty() 判断链表是否为空 leng

南风以南 361

SiC MOSFET驱动设计实战:从特性解析到电路优化

本文深入解析SiC MOSFET的核心特性及其驱动电路设计要点,涵盖高温稳定性、快速开关能力等关键特性,并提供驱动电压配置、电流能力计算、布局优化等实用方案。特别针对第三代电力电子半导体SiC MOSFET的驱动要求,分享STGAP1AS等典型驱动方案的应用技巧,助力工程师解决高频应用中的EMI和热管理挑战。

weixin_29230865的博客 365

【脑电分析系列】第15篇:脑电功能连接性与脑网络分析(二):Granger因果性、图论指标与复杂网络构建

摘要: 本文深入探讨了脑电(EEG)分析中的高阶连接性方法——有效连接(Effective Connectivity),重点介绍了Granger因果性(Granger Causality, GC)的原理与应用。GC通过统计预测揭示脑区间信息流动方向,超越了传统功能连接的同步性分析。文章还结合图论指标(如度、路径长度、聚类系数和模块化)量化脑网络的拓扑结构,并通过Python代码(MNE和NetworkX库)演示了从EEG数据构建、分析复杂脑网络的完整流程。该研究为理解大脑动态互动、认知任务信息流及神经系统疾

qq_32516809的博客 1560

单链表的访问。

单链表的访问: 只要我有头指针head,就可以通过其成员next继而找到下一个结点,以此类推可以访问所有的结点。 所谓的访问可以理解为取各个结点数据域的值进行一系列的操作,输出单向链表各个结点的数据域是最简单的访问链表的操作。 将链表中各个结点数据一次输出的步骤主要如下: (1),找到链表的头指针 (2),若链表非空,则输出结点的成员值。否则退出 (3),寻找下一个结点 (4),转到...

头秃程序员的日常 3460

matlab数学建模练习(2)练习电子科技大学数学实验

【代码】matlab数学建模练习(2)练习电子科技大学数学实验。

c_wrj_的博客 1435

数据结构:链表-笔记

1、链表都是线性数据结构;链表包括:单链表 双向链表 循环链表等。 2、在下列链表中不能从当前结点出发访问到其余各结点的是( )。 正确答案: C 你的答案: C (正确) 双向链表 单循环链表 单链表 双向循环链表 解析:只有单链表,是单向的。 3、在一个具有n个结点的有序单链表中插入一个新结点并保持该表有序的时间复杂度是_______。 正确答案: B 你的答案: B (正确) O(1) O(n) O(n2) O(log2n) 解析:需要先找到插入位置,也就是需要进行遍历一次O(n

世上再无张显宗 2737

【WRF后处理】基于wrf-python处理wrf运行结果wrfout_d01

基于wrf-python处理wrf运行结果wrfout_d01

WW、forever的博客 5209

BMS硬件设计要点:从STM32主控到BQ76920监控芯片的工程实践

电池管理系统(BMS)是锂电安全与寿命保障的核心,其硬件设计涉及微控制器选型、专用监控芯片接口、电源完整性、信号完整性及PCB布局等多维度协同。基于STM32与BQ76920的典型双层架构,需深入理解功能安全解耦原理——关键保护由ASIC硬件实现,算法决策交由MCU完成,契合ASIL-B等级要求。技术价值体现在毫秒级硬件保护响应、±10mV电压采样精度及抗EMI鲁棒性设计;广泛应用于电动工具、储能系统与轻型电动车等中高功率场景。本文聚焦BMS控制板硬件实现中的高频时钟EMC、I²C总线信号完整性、被动均衡可

weixin_30591519的博客 92

【链表】Reversing Linked List

Reversing Linked List 题目要求: Given a constant K and a singly linked list L, you are supposed to reverse the links of every K elements on L. For example, given L being 1→2→3→4→5→6, if K=3, then you must output 3→2→1→6→5→4; if K=4, you must output 4→3→2→1→5.

百栗.的博客 1151

【2025年阿里云暑期实习(算法岗)-4月24日-第一题(100分)- 小红听歌】(题目+思路+Java&C++&Python解析+在线测试)

小红正在听歌,屏幕上同时展示着歌词和对应的播放进度条。s1t101ti​0iti​1i小红每次可以操作快进或回退一个歌词(即将播放指针向右或向左移动一个位置),数据初始时和操作过程均保证已经播放的歌词是s的一个前缀(可为空串)。她的目标是:以尽可能少的操作次数,使得字符串s中未播放状态的歌词是"幸运串"。请你计算,为了达到该目标,至少需要多少次操作?(数据保证可以在有限次内完成操作目标)【幸运串】每种字母出现的次数为指定的次数,可为空串,具体可查看输入描述。

m0_73659489的博客 114

Strongswan linked_list_t链表 注释可独立运行测试

jingshaoyou的博客 686

STM32+FreeRTOS环境下LwIP协议栈移植详解

本文详细介绍了在STM32F407ZGT6平台上移植轻量级TCP/IP协议栈LwIP的过程。使用FreeRTOS操作系统和LAN8720A以太网PHY芯片,通过STM32CubeMX生成基础工程配置。重点包括LwIP源码的获取与工程集成、关键配置文件的编写(如lwipopts.h)、操作系统适配层sys_arch.c的实现,以及以太网接口驱动ethernetif.c的移植。文章特别强调内存管理、中断优先级、硬件校验和等关键配置项的注意事项,为基于STM32和LwIP的嵌入式网络开发提供了实用参考。

电脑管家 753

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

链表数据结构开源项目教程 —— HongKnight/linked-list

链表数据结构开源项目教程 —— HongKnight/linked-list 项目介绍 HongKnight/linked-list 是一个基于 GitHub 的链表数据结构实现开源项目,专注于提供链表(包括但不限于单链表、双链表以及可能的其他变种如循环链表)的 C++ 或者其他编程语言的实现示例。该项目旨在教育和研究目的,帮助开发者理解和操作链表这一基础且重要的数据结构。通过此项目,你可以学习到...

gitblog_00861的博客 532

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

链表Linked List

链表的动态的创建与删除

weixin_63145469的博客 1617

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

链表Linked list

单向链表概述定义:元素储存上并不连续分类单向链表:每个元素只知道下一个元素是谁双向链表:每个元素只知道上一个和下一个元素循环链表:尾节点指向头节点性能1)随机访问性能根据index找元素,时间复杂度O(n);2)插入(删除)中间插入:找索引O(n)+插入O(1)=O(n)起始插入:插入O(1)结尾插入:双向O(1)单向O(n)+O(1)=O(n)单向链表。

2301_78200937的博客 1025

C++ 链表 (linked list)

链表的概念 链表,顾名思义,是以链状形式存储的一系列数据。链状结构的特点是环环相扣 从一个节点只能走到相邻的下一个节点。链表中的每个节点我们一般用一个结构体来表示,每个节点实际存储位置在内存中是随机的,而不一定是顺序的。我们可以把链表的节点想象成购物商场的储物柜。商场里有很多储物柜,一个储物柜就像一个链表节点: struct ListNode { int data; } A; 储物柜上的编号...

qq_42885747的博客 2203

链表 Linked List(双向链表)

单链表与双链表的区别 单向链表,查找的方向只能是一个方向,而双向链表可以向前或者向后查找。 单向链表不能自我删除,需要靠辅助节点,而双向链表,则可以自我删除,所以单链表删除节点时,总是找到temp的下一个节点来删除的 双链表DoubleLinkedList 大部分代码与单链表的实例相同:单链表实例:单击前往 同理先创建一个Node节点类。区别在于需要添加一个指向前一个节点的变量pre; clas...

共勉 1021

Linked List 链表详解

本文是stanford cs library中两篇关于linked list的文章合体版 linked list basics linked list problems 我觉得这两篇讲linked list的文章写的非常非常好,所以在博客里自己写一下,也算是温习巩固数据结构的知识了 本文代码下载:http://download.youkuaiyun.com/detail/stevemarbo/

冯鹤伊的博客 1万+

数据结构——链表(Linked List)

使用单向环形链表解决Josephu问题,用不带头结点的单向循环链表先构成一个有n个节点的链表,然后由k节点起从1开始计数,直到第m时,对应节点删除,然后从被删除的下一个节点开始从1开始计数,直到最后一个节点被删除结束算法。2.temp.next = temp.next.next,也就是说需要删除节点的前一个节点本来指向的是删除节点,然后我们使其指向删除节点的下一个节点,直接跳过删除节点,这样该节点也就相当于被删除了。例如N=6,M=5,被杀掉的顺序是:5,4,6,2,3。1.单链表是以节点的方式来存储的。.

jishuxhengjiu的博客 1万+

链表 linked list

目录203 移除链表元素707 设计链表206 反转链表24 两两交换链表中的节点19 删除链表的倒数第n个节点02.07 链表相交142 环形链表Ⅱ 203 移除链表元素 easy 题目描述 给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 解题思路 # Definition for singly-linked list. # class ListNode: # def __init__(self, v

jiayue的博客 547

链表(Linked List)教程

双向链表,又称为双链表,是一种每个节点都有两个链接的链表,一个指向前一个节点,另一个指向后一个节点。循环链表是一种特殊的链表,其中最后一个节点的指针指向链表的第一个节点,形成一个闭环。一个简单的单向链表结构,包括头节点和几个后续节点,每个节点用圆圈表示,数据域内填写数据,指针域用箭头指向下一个节点。:对于图中的每个顶点,都有一个链表,链表中的节点包含两个信息:相邻顶点的标识和指向下一个相邻顶点的指针。:链表中的节点通常包含两个域:一个用于存储相邻顶点的信息,另一个用于存储指向链表中下一个节点的指针。

weixin_55485363的博客 1167
上一篇: clojure实战——binding vs let
下一篇: clojure实战——何时使用宏
蜗牛lz
博客等级 码龄15年 17粉丝 62原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值