浅谈c++中双向链表的用法

C++双链表各项操作(含代码) C++实现数据结构的双链表,写的不好,学习数据结构可以参考。 阅读详情

挺好的一篇文章,为什么不转载呢?

list 是顺序容器的一种。list 是一个双向链表。使用 list 需要包含头文件 list。双向链表的每个元素中都有一个在指针指向后一个元素,也有一个指针指向前一个元素,如图1所示。

在 list 容器中,在已经定位到要增删元素的位置的情况下,增删元素能在常数时间内完成。如图2所示,在 a_{i}和 a_{i+1} 之间插入一个元素,只需要修改a_{i}和 a_{i+1}  中的指针即可。

图1 :双向链表




图2:在双向链表中插入元素


list 容器不支持根据下标随机存取元素。

list 的构造函数和许多成员函数的用法都与 vector 类似,此处不再列举。除了顺序容器都有的成员函数外,list 容器还独有如表 1 所示的成员函数(此表不包含全部成员函数,且有些函数的参数较为复杂,表中只列出函数名)。

表1:list 的成员函数
成员函数或成员函数模板作  用
void push_front(const T & val)将 val 插入链表最前面
void pop_front()删除链表最前面的元素
void sort()将链表从小到大排序
void remove (const T & val)删除和 val 相等的元素
remove_if删除符合某种条件的元素
void unique()删除所有和前一个元素相等的元素
void merge(list <T> & x)将链表 x 合并进来并清空 x。要求链表自身和 x 都是有序的
void splice(iterator i, list <T> & x, iterator first, iterator last)在位置 i 前面插入链表 x 中的区间 [first, last),并在链表 x 中删除该区间。链表自身和链表 x 可以是同一个链表,只要 i 不在 [first, last) 中即可


表1中列出的成员函数有些是重载的,如 unique、merge、splice 成员函数都不止一个, 这里不再一一列举并解释。后面对于其他容器以及算法的介绍,对于有重载的情况也不再指出。要详细了解 STL,还需要查阅专门的 STL 手册,或查看编译器提供的联机帮助。

STL 中的算法 sort 可以用来对 vector 和 deque 排序,它需要随机访问迭代器的支持。因为 list 不支持随机访问迭代器,所以不能用算法 sort 对 list 容器排序。因此,list 容器引入了 sort 成员函数以完成排序。

list 的示例程序如下:

#include <list>  //使用 list 需要包含此头文件
#include <iostream>
#include <algorithm>  //使用STL中的算法需要包含此头文件
using namespace std;
class A {
private: int n;
public:
    A(int n_) { n = n_; }
    friend bool operator < (const A & a1, const A & a2);
    friend bool operator == (const A & a1, const A & a2);
    friend ostream & operator << (ostream & o, const A & a);
};
bool operator < (const A & a1, const A & a2) {
    return a1.n < a2.n;
}
bool operator == (const A & a1, const A & a2) {
    return a1.n == a2.n;
}
ostream & operator << (ostream & o, const A & a) {
    o << a.n;
    return o;
}
template <class T>
void Print(T first, T last)
{
    for (; first != last; ++first)
        cout << *first << " ";
    cout << endl;
}
int main()
{
    A a[5] = { 1, 3, 2, 4, 2 };
    A b[7] = { 10, 30, 20, 30, 30, 40, 40 };
    list<A> lst1(a, a + 5), lst2(b, b + 7);
    lst1.sort();
    cout << "1)"; Print(lst1.begin(), lst1.end());  //输出:1)1 2 2 3 4
    lst1.remove(2);  //删除所有和A(2)相等的元素
    cout << "2)"; Print(lst1.begin(), lst1.end());  //输出:2)1 3 4
    lst2.pop_front();  //删除第一个元素
    cout << "3)"; Print(lst2.begin(), lst2.end());  //输出:3)30 20 30 30 40 40
    lst2.unique();  //删除所有和前一个元素相等的元素
    cout << "4)"; Print(lst2.begin(), lst2.end());  //输出:4)30 20 30 40
    lst2.sort();
    lst1.merge(lst2);  //合并 lst2 到 lst1 并清空 lst2
    cout << "5)"; Print(lst1.begin(), lst1.end());  //输出:5)1 3 4 20 30 30 40
    cout << "6)"; Print(lst2.begin(), lst2.end());  //lst2是空的,输出:6)
    lst1.reverse();  //将 lst1 前后颠倒

    cout << "7)"; Print(lst1.begin(), lst1.end());  //输出 7)40 30 30 20 4 3 1
    lst2.insert(lst2.begin(), a + 1, a + 4);  //在 lst2 中插入 3,2,4 三个元素
    list <A>::iterator p1, p2, p3;
    p1 = find(lst1.begin(), lst1.end(), 30);
    p2 = find(lst2.begin(), lst2.end(), 2);
    p3 = find(lst2.begin(), lst2.end(), 4);
    lst1.splice(p1, lst2, p2, p3);  //将[p2, p3)插入p1之前,并从 lst2 中删除[p2,p3)
    cout << "8)"; Print(lst1.begin(), lst1.end());  //输出:8)40 2 30 30 20 4 3 1
    cout << "9)"; Print(lst2.begin(), lst2.end());  //输出:9)3 4
    return 0;
}


【实例】用 list 解决约瑟夫问题。

约瑟夫问题是:有 n 只猴子,按顺时针方向围成一圈选大王(编号为 1~n),从第 1 号开始报数,一直数到 m,数到 m 的猴子退到圈外,剩下的猴子再接着从 1 开始报数。就这样,直到圈内只剩下一只猴子时,这个猴子就是猴王。编程求输入 n、m 后,输出最后猴王的编号。

输入数据:每行是用空格分开的两个整数,第一个是 n,第二个是 m(0<m, n<=1 000 000)。最后一行是:
0 0

输出要求:对于每行输入数据(最后一行除外),输出数据也是一行,即最后猴王的编号。

输入样例:
6 2
12 4
8 3
0 0

输出样例:
5
1
7

示例程序如下:

#include <list>
#include <iostream>
using namespace std;
int main()
{
    list<int> monkeys;
    int n, m;
    while (true) {
        cin >> n >> m;
        if (n == 0 && m == 0)
            break;
        monkeys.clear();  //清空list容器
        for (int i = 1; i <= n; ++i)  //将猴子的编号放入list
            monkeys.push_back(i);
        list<int>::iterator it = monkeys.begin();
        while (monkeys.size() > 1) { //只要还有不止一只猴子,就要找一只猴子让其出列
            for (int i = 1; i < m; ++i) { //报数
                ++it;
                if (it == monkeys.end())
                    it = monkeys.begin();
            }
            it = monkeys.erase(it); //删除元素后,迭代器失效,
                                    //要重新让迭代器指向被删元素的后面
            if (it == monkeys.end())
                it = monkeys.begin();
        }
        cout << monkeys.front() << endl; //front返回第一个元素的引用
    }
    return 0;
}

erase 成员函数返回被删除元素后面那个元素的迭代器。如果被删除的是最后一个元素,则返回 end()。

这个程序也可以用 vector 实现,但是执行速度要慢很多。因为 vector 的 erase 操作牵涉元素的移动,不能在常数时间内完成,所花费的时间和容器中的元素个数有关;而 list 的 erase 操作只是修改几个指针而已,可以在常数时间内完成。当 n 很大(数十万)时,两种写法在速度上会有明显区别。

 转载文章,若发现不允许转载,确认后会立即删除本文

鸿蒙OpenHarmony技术:【Docker编译环境】 OpenHarmony为开发者提供了两种Docker环境,以帮助开发者快速完成复杂的开发环境准备工作。独立Docker环境:适用于直接基于Ubuntu、Windows操作系统平台进行版本编译的场景。基于HPM的Docker环境:适用于使用HPM工具进行发行版编译的场景。点击或者复制转到。表1Docker镜像介绍系统类型运行平台Docker镜像仓库标签标准系统(独立Docker环境)3.2小型系统(独立Docker环境)3.2轻量系统(独立Docker环境)3.2。 阅读详情

相关推荐

《机器学习》周志华_自学记录

第一章绪论## 1.1引言机器学习所研究的主要内容,是关于在计算机上从数据中产生"模型"(model)的算法,即"学习算法"(learning algorithm).在面对新的情况时(例如看到一个没剖开的西瓜),模型会给我们提供相应的判断(例如好瓜).如果说计算机科学是研究关于"算法"的学问,那么类似的,可以说机器学习是研究关于"学习算法"的学问.## 1.2基本术语:用于预测离散值,例如将样本分为“好瓜”或“坏瓜”。:用于预测连续值,例如西瓜的成熟度(如0.95、0.37)。

2201_75296678的博客 2531

C++数据结构之双链表详解

这里头节点是不存储数据的,且单向链表的操作,双向链表都可以做到,这里讲一下双向链表的特点。如果想看一些基础的增删改查工作,直接查看单链表即可。

suren_jun的博客 1488

SOC-ATF 安全启动BL2流程分析(2)

Bl2的启动流程与bl1类似,主要区别是bl2的初始化流程比bl1更简单,但其可能需要加载更多的镜像,如bl31、bl32和bl33。由于bl2可以运行于el3或s-el1,它们的入口函数和处理流程都有所区别,为了简化分析我们选取比较常见的s-el1方式,以下为其总体执行流程:上图仅供参考,实际看一下代码结构:上面截图展示了 链接汇编文件,bl2_el3.ld.S 是指bl2 运行于el3;bl2.ld.S 是实现bl2运行于s-el1 .

z20230508的博客 1388

使用C++实现双链表

c++实现的双链表

qq_58240448的博客 3884

解决 python2.7中 ImportError: No module named Crypto.Signature

我的解决办法,先查看有没有安装 pip,直接执行pip 回车 没有出现null什么的就安装了,如果没有安装去其他博客哪里看一下,正常情况是默认就有的,然后使用。发现我自己也不会啊,就百度看看,想着网上的解决方法一大片,但是都是废话,能用的没有几个,而且能安装的没有几个。这个里面的python2、3就是系统里面的python版本,直接跟我这样就可以了除非版本不一样,也就是没有这个版本。就可以使用了,第一个应该是卸载之前的,然后重新安装,我的就是这样解决的。就比如我的,我现在使用的 python2.7。

记录一下 1610

YOLO11改进 | 主干网络 | 添加Hyper-YOLO的MANet混合聚合网络

本文详细介绍了在YOLO11目标检测模型中替换C3k2模块为MANet的具体实现方法。文章首先讲解MANet模块的原理,然后分步骤指导如何在YOLO11中添加该模块,包括代码修改、文件配置和模型注册等关键环节。通过实验对比,改进后的YOLO11_MANet模型在保持8.8GFLOPs计算量的同时,参数数量达到3,820,272,网络层数增加到343层。文章还提供了完整的代码实现和网络结构图,并建议结合其他注意力机制或损失函数进一步提升检测效果。最后推荐了相关的深度学习专栏,包含更多YOLO系列改进方法。

kay_545 660

C/C++双向链表的各种操作

运行环境:VS2022 X64。

qq_35803412的博客 401

大津法(OTSU)点云强度信息分割

大津法(OTSU)是一种灰度图像自适应的阈值分割方法,大津法根据图像的灰度分布,将图像分成背景和前景两部分,前景就是需要按照阈值分割出来的部分。由于点云的强度信息的特性,也可以利用此方法进行分类,但需要保证信息干扰较少,例如道路标线分割等场景较为适用。

qq_48694523的博客 965

C++ 双链表基本操作

双链表基本操作

qq_40423330的博客 368

笔试题-2023-乐鑫-数字IC设计【纯净题目版】

笔试题-2023-乐鑫-数字IC设计【纯净题目版】

w0shishabi的博客 1777

RK3588网卡出现丢包或者带宽不足的问题验证排查

注意除了有最大的TCP数据接收缓冲,还有/proc/sys/net/core/wmem_max — 最大的TCP数据发送缓冲可以调整,这里暂时没用到,针对具体需要可适当调整。比如把ethx接口中断从默认的cpu0迁移到其它cpu,例如将eth0中断234移到cpu7 (10是16进制, cpu0 =3588的cpu有8个核,4个A55(小核)+4个A76(大核),可以找到对应中断 将中断从默认cpu0核切到cpu7。tcp_rmem:单位是字节,接收缓存区大小,缓存从对端接收的数据,后续会被应用程序读取。

Android/Linux驱动开发传帮带学习,让驱动入门门槛更低! 2030

浅谈双向链表

介绍双向链表的基础知识

wcqqq的博客 438

《AgentScope-Java 深入浅出教程》第10章 RAG 知识检索

RAG(Retrieval-Augmented Generation,检索增强生成)是一种将信息检索与文本生成相结合的技术架构。它通过从外部知识库中检索相关文档,将检索到的信息作为上下文注入到语言模型的提示中,从而增强模型的回答质量。│ RAG 工作流程 ││ ││ 用户问题 向量检索 上下文增强 生成回答 ││ ▼ ││ │ A │ ││ ││ 1. 接收问题 ││ 2. 将问题转换为向量,在知识库中检索相似文档 ││ 3. 将检索到的文档作为上下文添加到提示词中 │。

步子哥的博客 462

浅谈链表应用

题面传送门 链表,顾名思义,就是一根链,由许多节点构成,每个节点分为两个部分:数据域和指针域,其中数据域可以包含很多数据,指针域只能包含一个指向对象,不然就成图了。链表可以O(1)O(1)O(1)插入和删除数据,但不能随机访问元素。 链表实现就不再乱说了。毕竟是个人都会。主要讲一些链表的应用。 这道题很简单,只要顺着链表找下去,找到第m个点就删掉就好了。 代码实现: #include<cst...

fxt275307894a的博客 198

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

浅谈C/C++指针、地址、内存空间、链表&新手常见误区

2021.8.28 浅谈指针、地址、内存空间、链表&新手常见误区 -1 几个问题 c/c++中一个指针的大小是多少?int*、double*、Node*大小分别是多少? Node型变量大小为什么是16字节,不是12字节? 一个节点Node到底长什么样? head指针和头节点一样吗? 每句代码在内存中究竟做了什么操作? 0 写在前面 数据结构重要。 本文适合完整的学过c++,但是对「指针、地址、内存空间、链表的理解与实现」仍存在模糊的初学者。 如果未完整的学过c++,学过c的指针,可以看到「指.

Ludwig1957的博客 1173

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

浅谈STL list<T>链表容器和迭代器的使用C++实现

一、今天简单的实现了STL容器里面的顺序容器list双链表里面的简单应用和迭代器的简单实现方法    包括迭代器的重载方法     二、双向链表的实现需要了解 堆得内存分配问题。堆内存是开发者使用new开辟的空间 需要开发者自己释放掉内存 否者将会存在内存中知道程序结束    所以对内存的释放很重要。当了解了堆和栈的分配之后将会更加容易理解链表的节点的实现方法。   三、关于栈内存的分配将

whisperfor的博客 2305

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

【C++】浅谈list

浅谈listlist的介绍及其使用list介绍list功能使用list的构造llist iterator的使用list capacitylist element accesslist modifierslist的迭代器失效模拟实现list迭代器模拟实现代码vector与list的对比 list的介绍及其使用 list介绍 在STL当中最主要的就是带头双向循环列表 list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。 list的底层是双向链表结构,双向链表中每个元素存

Anton的博客 568

C++ 浅谈之 STL List

STL List 底层实现

优质后端技术知识记录 498

从C++开始的编程生活(13)——list和浅谈stack、queue

第13篇主要讲的是有关于C++的list和浅谈stack、queue。

Elnaij的博客 479

Data Structures in C++:链表

C++实现

水木年崋 353

浅谈单链表与双链表的区别

数组的优点 随机访问性强(通过下标进行快速定位) 查找速度快 数组的缺点 插入和删除效率低(插入和删除需要移动数据) 可能浪费内存(因为是连续的,所以每次申请数组之前必须规定数组的大小,如果大小不合理,则可能会浪费内存) 内存空间要求高,必须有足够的连续内存空间。 数组大小固定,不能动态拓展 链表的优点 插入删除速度快(因为有next指针指向其下一个节点,通过改变指针的指向可以方便的增加删除元素)...

代码学习之路的博客 375

浅谈C++|STL之list+forward_list篇

将数据进行链式存储(list)是一种物理存储单元上非连续的存储结构,数据元素的逻辑顺序是通过链表中的指针链接实现的链表的组成:链表由—系列组成结点的组成:一个是存储数据元素的,另一个是存储下一个结点地址的STL中的链表是一个由于链表的存储方式并不是连续的内存空间,因此链表list中的迭代器只支持前移和后移,属于双向迭代器·采用动态存储分配,不会造成内存浪费和溢出·链表执行插入和删除操作十分方便,修改指针即可,不需要移动大量元素·链表灵活,但是空间(指针域)和时间(遍历)额外耗费较大。

m0_73731708的博客 653

GTK+浅谈之总结

一、简介        GTK+的一些知识点总结,方便以后查阅。 二、详解 1、G_BEGIN_DECLS和G_END_DECLS宏 #ifdef __cplusplus # define G_BEGIN_DECLS extern "C" { # define G_END_DECLS } #else # define G_BEGIN_DECLS # define G_

乌托邦 2079

c++ vector 先进先出_浅谈C++容器

在面向对象程序中,大多引入了容器的概念。那么什么是容器?实质上是一组相同类型对象的集合,但它不仅仅是数组那么简单,它实现了比数组更复杂的数据结构,能够实现更复杂的功能。C++标准模版库里提供了10种通用的容器,它基本可以解决程序中遇到的大部分问题。什么是容器C++中容器的定义如下:数据存储上,有一种对象类型,它可以持有其他对象或指向其他对象的指针,这种对象类型叫容器。通俗的说容器就是保存其他对象的...

weixin_39936388的博客 3492

STL学习——浅谈List类的模拟实现

       本文模拟实现了c++标准模板库中的List。 它的底层实现是一个带头结点的双向循环链表。        一个注意要点是,不同于vector和string的迭代器的封装 typedef T* Iterator List 采用了一个类来封装迭代器...

现从事游戏开发领域 | 团队项目be_with开发进行中 web方向感兴趣者私 ——We can do all things. 441

浅谈C++算法

C++ 是一种功能强大的编程语言,常用于系统/应用软件、游戏开发、高性能服务器和实时模拟等领域。在C++中实现算法时,你可以使用标准模板库(STL)提供的数据结构和算法,也可以自己编写算法。1、向量(Vector):动态数组,可以自动调整大小。2、列表(List):双向链表,允许快速插入和删除。3、集合(Set):不允许重复的元素集合,自动排序。4、映射(Map):基于键值对的集合,键不允许重复,自动排序。5、队列(Queue):先进先出(FIFO)的数据结构。6、栈(Stack)

a876106354的博客 509
上一篇: 初级动态规划(DP、背包)问题模板
下一篇: 浅谈C++位运算----赠送进制转换代码
智慧派蒙
博客等级 码龄5年 4粉丝 7原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值