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 双向遍历,插入删除更灵活
循环链表 单向 / 双向 指向表头 / 头结点 环形遍历,适合循环场景

单链表的功能实现

定义

头插

遍历

按值查找

删除任意位置之后的元素

双向链表

头插

按值查找

任意位置之后插入元素

相关推荐
西哥写代码5 小时前
基于dcmtk的dicom工具 第十章 读取dicom文件图像数据并显示
c++·mfc·dcmtk·vs2017
澪吟7 小时前
数据结构入门:深入理解顺序表与链表
数据结构·链表
大数据张老师7 小时前
数据结构——直接插入排序
数据结构·算法·排序算法·1024程序员节
lsnm8 小时前
C++新手项目-JsonRPC框架
开发语言·c++·1024程序员节
给大佬递杯卡布奇诺8 小时前
FFmpeg 基本数据结构 AVPacket分析
数据结构·c++·ffmpeg·音视频
南方的狮子先生9 小时前
【数据结构】从线性表到排序算法详解
开发语言·数据结构·c++·算法·排序算法·1024程序员节
程序猿编码9 小时前
Linux 文件变动监控工具:原理、设计与实用指南(C/C++代码实现)
linux·c语言·c++·深度学习·inotify
极客智造9 小时前
编程世界的内在逻辑:深入探索数据结构、算法复杂度与抽象数据类型
数据结构·算法·数学建模