C++数据结构(链表和list)

链表的定义

链表 :用链式存储实现的线性表。

链式存储:在内存中,不仅存储当前元素的信息,还存储前继或后继结点的地址。通过地址实现元素与元素之间的关系。

单链表、带头链表(头结点链表)、双向链表、循环链表的基础定义

1. 单链表(Singly Linked List)

定义 :每个节点包含数据域和一个指向后继节点的指针,最后一个节点的指针为nullptr特点:只能从表头向表尾遍历,插入 / 删除需修改前驱节点的指针。

复制代码
// 节点结构
template <typename T>
struct SinglyNode {
    T data;               // 数据域
    SinglyNode<T>* next;  // 指向后继节点的指针

    // 构造函数
    SinglyNode(const T& val) : data(val), next(nullptr) {}
};

// 单链表类(不带头节点)
template <typename T>
class SinglyLinkedList {
private:
    SinglyNode<T>* head;  // 头指针(指向第一个节点)
public:
    SinglyLinkedList() : head(nullptr) {}
    // 其他成员函数(插入、删除、遍历等)
};

2. 带头链表(头结点链表,Singly Linked List with Head Node)

定义 :在单链表的基础上增加一个头结点 (不存储实际数据),头指针指向头结点,头结点的next指向第一个实际节点。特点:统一空表和非空表的操作逻辑(无需特殊处理头指针),简化插入 / 删除代码。

复制代码
// 节点结构(同单链表)
template <typename T>
struct HeadNode {
    T data;               // 头结点可闲置或存长度等信息
    HeadNode<T>* next;

    HeadNode() : next(nullptr) {}  // 头结点默认构造
};

// 带头链表类
template <typename T>
class HeadLinkedList {
private:
    HeadNode<T>* head;  // 头指针(指向头结点)
public:
    HeadLinkedList() {
        head = new HeadNode<T>();  // 初始化头结点
    }
    // 其他成员函数
};

3. 双向链表(Doubly Linked List)

定义 :每个节点包含数据域、指向后继节点的指针(next)和指向前驱节点的指针(prev)。特点:可双向遍历,插入 / 删除时需同时修改前驱和后继的指针,但操作更灵活。

复制代码
// 节点结构
template <typename T>
struct DoublyNode {
    T data;                // 数据域
    DoublyNode<T>* prev;   // 指向前驱节点
    DoublyNode<T>* next;   // 指向后继节点

    DoublyNode(const T& val) : data(val), prev(nullptr), next(nullptr) {}
};

// 双向链表类(可带头结点,此处示例带头结点)
template <typename T>
class DoublyLinkedList {
private:
    DoublyNode<T>* head;  // 头指针(指向头结点)
public:
    DoublyLinkedList() {
        head = new DoublyNode<T>(T());  // 头结点
        head->prev = head->next = head;  // 若为循环双向链表则指向自身
    }
    // 其他成员函数
};

4. 循环链表(Circular Linked List)

定义 :最后一个节点的指针不指向nullptr,而是指向表头(单循环)或头结点(带头循环),形成闭环。双向循环链表中,头结点的prev指向尾节点。特点:可从任意节点遍历整个链表,适合实现环形队列等场景。

(1)单循环链表(带头结点)
复制代码
template <typename T>
struct CircSinglyNode {
    T data;
    CircSinglyNode<T>* next;

    CircSinglyNode(const T& val) : data(val), next(nullptr) {}
};

template <typename T>
class CircSinglyLinkedList {
private:
    CircSinglyNode<T>* head;  // 头结点
public:
    CircSinglyLinkedList() {
        head = new CircSinglyNode<T>(T());
        head->next = head;  // 头结点next指向自身(空表)
    }
    // 插入节点后,尾节点next需指向head
};
(2)双向循环链表(带头结点)
复制代码
// 节点结构同双向链表的DoublyNode
template <typename T>
class CircDoublyLinkedList {
private:
    DoublyNode<T>* head;
public:
    CircDoublyLinkedList() {
        head = new DoublyNode<T>(T());
        head->prev = head;  // 头结点prev指向自身
        head->next = head;  // 头结点next指向自身
    }
    // 尾节点next指向head,head->prev指向尾节点
};

核心区别总结

类型 指针方向 尾节点指针 核心优势
单链表 单向(next) nullptr 结构简单,内存开销小
带头链表 单向(next) nullptr 统一操作逻辑,简化代码
双向链表 双向(prev+next) nullptr 双向遍历,插入删除更灵活
循环链表 单向 / 双向 指向表头 / 头结点 环形遍历,适合循环场景

单链表的功能实现

定义

头插

遍历

按值查找

删除任意位置之后的元素

双向链表

头插

按值查找

任意位置之后插入元素

相关推荐
郝学胜_神的一滴6 小时前
CMake 034:生成器表达式:解耦构建时序、精简分支逻辑的终极利器
c++·cmake
见过夏天21 小时前
C++ 基础入门完全指南
c++
CSharp精选营2 天前
关系型 vs 非关系型:从原理到选型,一文搞定数据库核心分类
数据结构·nosql·关系型数据库·非关系型数据库·技术选型
用户805533698032 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
BadBadBad__AK3 天前
线段树维护区间 k 次方和
c++·数学·算法·stl
卷无止境3 天前
Eigen 库如何借助 OpenMP 加速计算
c++·后端
卷无止境3 天前
OpenMPI、MPICH 与 OpenMP:关系、核心概念与架构全解
c++·后端
郝学胜_神的一滴4 天前
CMake 30:循环语法全解|foreach_while双循环精讲、迭代技巧与实战避坑指南
c++·cmake
刘马想放假5 天前
Modbus 全栈技术解析:TCP、RTU、ASCII、RTU over TCP
数据结构·网络协议
北域码匠6 天前
冒泡排序太慢?鸡尾酒排序双向优化,原生 C# 零第三方库完整代码
数据结构·排序算法·泛型·c# 算法·鸡尾酒排序·原生 c# 开发·冒泡排序优化·嵌入式算法