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

单链表的功能实现

定义

头插

遍历

按值查找

删除任意位置之后的元素

双向链表

头插

按值查找

任意位置之后插入元素

相关推荐
研究点啥好呢4 小时前
Github热门项目推荐 | 创建你的像素风格!
c++·python·node.js·github·开源软件
_dindong4 小时前
cf1091div2 C.Grid Covering(数论)
c++·算法
沫璃染墨4 小时前
C++ string 从入门到精通:构造、迭代器、容量接口全解析
c语言·开发语言·c++
skywalker_114 小时前
力扣hot100-3(最长连续序列),4(移动零)
数据结构·算法·leetcode
6Hzlia4 小时前
【Hot 100 刷题计划】 LeetCode 17. 电话号码的字母组合 | C++ 回溯算法经典模板
c++·算法·leetcode
_日拱一卒5 小时前
LeetCode:除了自身以外数组的乘积
数据结构·算法·leetcode
计算机安禾5 小时前
【数据结构与算法】第36篇:排序大总结:稳定性、时间复杂度与适用场景
c语言·数据结构·c++·算法·链表·线性回归·visual studio
unicrom_深圳市由你创科技5 小时前
做虚拟示波器这种实时波形显示的上位机,用什么语言?
c++·python·c#
无限进步_5 小时前
【C++】电话号码的字母组合:从有限处理到通用解法
开发语言·c++·ide·windows·git·github·visual studio
计算机安禾5 小时前
【数据结构与算法】第35篇:归并排序与基数排序
c语言·数据结构·vscode·算法·排序算法·哈希算法·visual studio