C++中的链表操作

在C++中,链表是一种常见的数据结构,它由一系列节点组成,每个节点包含数据部分和指向下一个节点的指针。C++标准库(STL)中提供了std::liststd::forward_list两种链表实现,分别对应双向链表和单向链表。此外,也可以通过手动实现链表来加深对链表的理解。

1. C++标准库中的链表

(1)std::list(双向链表)

std::list是C++标准库中的双向链表实现,每个节点包含指向前一个节点和后一个节点的指针。它支持高效的插入和删除操作,但随机访问效率较低。

  • 基本操作

    #include <iostream>
    #include <list>int main() {std::list<int> myList;// 插入元素myList.push_back(10); // 在链表尾部插入myList.push_front(20); // 在链表头部插入myList.insert(myList.begin() + 1, 30); // 在指定位置插入// 遍历链表for (int value : myList) {std::cout << value << " ";}std::cout << std::endl;// 删除元素myList.pop_back(); // 删除尾部元素myList.pop_front(); // 删除头部元素myList.erase(myList.begin() + 1); // 删除指定位置的元素// 遍历链表for (int value : myList) {std::cout << value << " ";}std::cout << std::endl;return 0;
    }
(2)std::forward_list(单向链表)

std::forward_list是C++11引入的单向链表实现,每个节点只包含指向下一个节点的指针。它比std::list更轻量,但只能单向遍历。

  • 基本操作

    #include <iostream>
    #include <forward_list>int main() {std::forward_list<int> myList;// 插入元素myList.push_front(10); // 在链表头部插入myList.push_front(20);myList.insert_after(myList.begin(), 30); // 在指定位置插入// 遍历链表for (int value : myList) {std::cout << value << " ";}std::cout << std::endl;// 删除元素myList.pop_front(); // 删除头部元素myList.erase_after(myList.begin()); // 删除指定位置的元素// 遍历链表for (int value : myList) {std::cout << value << " ";}std::cout << std::endl;return 0;
    }

2. 手动实现链表

手动实现链表可以帮助更好地理解链表的内部机制。以下是单向链表和双向链表的基本实现。

(1)单向链表
#include <iostream>// 定义链表节点
struct Node {int data;Node* next;Node(int value) : data(value), next(nullptr) {}
};// 定义链表类
class LinkedList {
private:Node* head;public:LinkedList() : head(nullptr) {}// 插入元素到链表尾部void append(int value) {Node* newNode = new Node(value);if (head == nullptr) {head = newNode;} else {Node* current = head;while (current->next != nullptr) {current = current->next;}current->next = newNode;}}// 插入元素到链表头部void prepend(int value) {Node* newNode = new Node(value);newNode->next = head;head = newNode;}// 删除元素void remove(int value) {if (head == nullptr) return;if (head->data == value) {Node* temp = head;head = head->next;delete temp;return;}Node* current = head;while (current->next != nullptr && current->next->data != value) {current = current->next;}if (current->next != nullptr) {Node* temp = current->next;current->next = temp->next;delete temp;}}// 遍历链表void print() const {Node* current = head;while (current != nullptr) {std::cout << current->data << " ";current = current->next;}std::cout << std::endl;}// 析构函数,释放链表内存~LinkedList() {Node* current = head;while (current != nullptr) {Node* temp = current;current = current->next;delete temp;}}
};int main() {LinkedList list;list.append(10);list.append(20);list.prepend(5);list.print(); // 输出:5 10 20list.remove(10);list.print(); // 输出:5 20return 0;
}
(2)双向链表
#include <iostream>// 定义链表节点
struct Node {int data;Node* next;Node* prev;Node(int value) : data(value), next(nullptr), prev(nullptr) {}
};// 定义链表类
class DoublyLinkedList {
private:Node* head;Node* tail;public:DoublyLinkedList() : head(nullptr), tail(nullptr) {}// 插入元素到链表尾部void append(int value) {Node* newNode = new Node(value);if (head == nullptr) {head = newNode;tail = newNode;} else {tail->next = newNode;newNode->prev = tail;tail = newNode;}}// 插入元素到链表头部void prepend(int value) {Node* newNode = new Node(value);if (head == nullptr) {head = newNode;tail = newNode;} else {newNode->next = head;head->prev = newNode;head = newNode;}}// 删除元素void remove(int value) {Node* current = head;while (current != nullptr && current->data != value) {current = current->next;}if (current == nullptr) return;if (current->prev != nullptr) {current->prev->next = current->next;} else {head = current->next;}if (current->next != nullptr) {current->next->prev = current->prev;} else {tail = current->prev;}delete current;}// 遍历链表void print() const {Node* current = head;while (current != nullptr) {std::cout << current->data << " ";current = current->next;}std::cout << std::endl;}// 析构函数,释放链表内存~DoublyLinkedList() {Node* current = head;while (current != nullptr) {Node* temp = current;current = current->next;delete temp;}}
};int main() {DoublyLinkedList list;list.append(10);list.append(20);list.prepend(5);list.print(); // 输出:5 10 20list.remove(10);list.print(); // 输出:5 20return 0;
}

总结

  • 标准库链表std::liststd::forward_list提供了丰富的功能和高效的插入删除操作,适合大多数应用场景。

  • 手动实现链表:通过手动实现链表,可以加深对链表内部机制的理解,例如节点的创建、插入、删除和内存管理等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/76528.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

蛋白设计 ProteinMPNN

传统方法的局限性是什么&#xff1f; 传统蛋白质设计方法的局限性&#xff1a; 基于物理的传统方法&#xff0c;例如罗塞塔&#xff0c;面临计算难度&#xff0c;因为需要计算所有可能结构的能量&#xff0c;包括不需要的寡聚态和聚合态。 设计目标与显式优化之间缺乏一致性通…

有哪些开源的视频生成模型

1. 阿里巴巴通义万相2.1&#xff08;WanX 2.1&#xff09; 技术架构&#xff1a;基于Diffusion Transformer&#xff08;DiT&#xff09;架构&#xff0c;结合自研的高效变分自编码器&#xff08;VAE&#xff09;和Flow Matching训练方案&#xff0c;支持时空上下文建模。参数…

【动态规划】最长上升子序列模板

最长上升子序列 题目传送门 一、题目描述 给定一个长度为 N 的数列&#xff0c;求数值严格单调递增的子序列的长度最长是多少。 输入格式 第一行包含整数 N。 第二行包含 N 个整数&#xff0c;表示完整序列。 输出格式 输出一个整数&#xff0c;表示最大长度。 数据范围 …

LeetCode 891 -- 贡献度思想

题目描述 子序列宽度之和 思路 ref 代码 相似题 子数组范围和 acwing

化工行业如何通过定制化工作流自动化实现25-30%成本优化?

作者&#xff1a;Mihir Jhaveri 编译&#xff1a;李升伟 发布日期&#xff1a;2024年10月30日 在化工生产领域&#xff0c;数字化转型正以颠覆性态势重塑产业格局。通过集成定制化软件、ERP系统、工业物联网&#xff08;IIoT&#xff09;传感网络、机器人流程自动化&#xff0…

Compose组件转换XML布局

文章目录 学习JetPack Compose资源前言&#xff1a;预览界面的实现Compose组件的布局管理一、Row和Colum组件&#xff08;LinearLayout&#xff09;LinearLayout&#xff08;垂直方向 → Column&#xff09;LinearLayout&#xff08;水平方向 → Row&#xff09; 二、相对布局 …

RAG测试数据集资源

一、通用问答基准数据集 HotpotQA 特点:包含11万+多跳问答对最佳用途:测试复杂推理能力数据示例:{"question": "Were Scott Derrickson and Ed Wood of the same nationality?","answer": "Yes, both are American" }MS MARCO 特点…

快速掌握MCP——Spring AI MCP包教包会

最近几个月AI的发展非常快&#xff0c;各种大模型、智能体、AI名词和技术和框架层出不穷&#xff0c;作为一个业余小红书博主的我最近总刷到MCP这个关键字&#xff0c;看着有点高级我也来学习一下。 1.SpringAI与functionCall简单回顾 前几个月我曾写过两篇关于SpringAI的基础…

学习笔记--(6)

import numpy as np import matplotlib.pyplot as plt from scipy.special import erfc# 设置参数 rho 0.7798 z0 4.25 # 确保使用大写 Z0&#xff0c;与定义一致def calculate_tau(z, z_prime, rho, s_values):return np.log(rho * z * z_prime * s_values / 2)# 定义 chi_…

【AI4CODE】5 Trae 锤一个基于百度Amis的Crud应用

【AI4CODE】目录 【AI4CODE】1 Trae CN 锥安装配置与迁移 【AI4CODE】2 Trae 锤一个 To-Do-List 【AI4CODE】3 Trae 锤一个贪吃蛇的小游戏 【AI4CODE】4 Trae 锤一个数据搬运工的小应用 1 百度 Amis 简介 百度 Amis 是一个低代码前端框架&#xff0c;由百度开源。它通过 J…

认识 Promise

认识 Promise 前言&#xff1a;为什么会出现 Promise&#xff1f; 最常见的一个场景就是 ajax 请求&#xff0c;通俗来说&#xff0c;由于网速的不同&#xff0c;可能你得到返回值的时间也是不同的&#xff0c;这个时候我们就需要等待&#xff0c;结果出来了之后才知道怎么样…

纯c++实现transformer 训练+推理

项目地址 https://github.com/freelw/cpp-transformer C 实现的 Transformer 这是一个无需依赖特殊库的 Transformer 的 C 实现&#xff0c;涵盖了训练与推理功能。 本项目使用C复刻了《Dive into Deep Learning》中关于 Transformer 的第 11 章11.7小节点内容。构建了一个英…

Go 语言规范学习(7)

文章目录 Built-in functionsAppending to and copying slicesClearCloseManipulating complex numbersDeletion of map elementsLength and capacityMaking slices, maps and channelsMin and maxAllocationHandling panicsBootstrapping PackagesSource file organizationPac…

Python Cookbook-5.1 对字典排序

任务 你想对字典排序。这可能意味着需要先根据字典的键排序&#xff0c;然后再让对应值也处于同样的顺序。 解决方案 最简单的方法可以通过这样的描述来概括:先将键排序&#xff0c;然后由此选出对应值: def sortedDictValues(adict):keys adict.keys()keys.sort()return …

Git Rebase 操作中丢失提交的恢复方法

背景介绍 在团队协作中,使用 Git 进行版本控制是常见实践。然而,有时在执行 git rebase 或者其他操作后,我们可能会发现自己的提交记录"消失"了,这往往让开发者感到恐慌。本文将介绍几种在 rebase 后恢复丢失提交的方法。 问题描述 当我们执行以下操作时,可能…

C语言基础要素(019):输出ASCII码表

计算机以二进制处理信息&#xff0c;但二进制对人类并不友好。比如说我们规定用二进制值 01000001 表示字母’A’&#xff0c;显然通过键盘输入或屏幕阅读此数据而理解它为字母A&#xff0c;是比较困难的。为了有效的使用信息&#xff0c;先驱者们创建了一种称为ASCII码的交换代…

鸿蒙定位开发服务

引言 鸿蒙操作系统&#xff08;HarmonyOS&#xff09;作为面向万物互联时代的分布式操作系统&#xff0c;其定位服务&#xff08;Location Kit&#xff09;为开发者提供了多场景、高精度的位置能力支持。本文将从技术原理、开发流程到实战案例&#xff0c;全面解析鸿蒙定位服务…

rknn_convert的使用方法

rknn_convert是RKNN-Toolkit2提供的一套常用模型转换工具&#xff0c;通过封装上述API接口&#xff0c;用户只需编辑模型对应的yml配置文件&#xff0c;就可以通过指令转换模型。以下是如何使用rknn_convert工具的示例命令以及支持的指令参数&#xff1a; python -m rknn.api.…

解决 axios get请求瞎转义问题

在Vue.js项目中&#xff0c;axios 是一个常用的HTTP客户端库&#xff0c;用于发送HTTP请求。qs 是一个用于处理查询字符串的库&#xff0c;通常与 axios 结合使用&#xff0c;特别是在处理POST请求时&#xff0c;将对象序列化为URL编码的字符串。 1. 安装 axios 和 qs 首先&a…

【XTerminal】【树莓派】Linux系统下的函数调用编程

目录 一、XTerminal下的Linux系统调用编程 1.1理解进程和线程的概念并在Linux系统下完成相应操作 (1) 进程 (2)线程 (3) 进程 vs 线程 (4)Linux 下的实践操作 1.2Linux的“虚拟内存管理”和stm32正式物理内存&#xff08;内存映射&#xff09;的区别 (1)Linux虚拟内存管…