Skip to content

带头结点的链表

头节点引入原因

  • 链表操作中获取长度需要遍历计数,占用CPU资源
  • 头节点用于存储链表属性信息,避免频繁遍历

头节点定义

cpp
struct HeadNode {
    int length;        // 链表长度
    NodeType* first;   // 首结点地址
    NodeType* final;   // 尾结点地址
};

头节点特性

  1. 不参与链表长度计数
  2. 不参与链表遍历
  3. 不作为链表数据结点
  4. 专门存储链表信息

创建步骤

从无到有创建

加入第一个结点

增加后续结点

删除结点

  1. 删除首结点时更新first指针
  2. 删除尾结点时更新final指针
  3. 删除中间结点时维护前后链接
  4. 更新头节点中的length

循环链表

循环单链表

定义

最后一个数据结点的next指针指向首结点

创建方法

  1. 创建普通单链表
  2. 将尾结点的next指针指向首结点

循环双链表

定义

创建方法

  1. 将尾结点的next指针指向首结点
  2. 将首结点的prev指针指向尾结点

循环链表遍历方法

方法一

  1. 临时指针指向首结点
  2. 循环条件:temp->next != head
  3. 循环结束后单独处理尾结点

方法二

cpp
Node* start = head;
Node* current = head;

do {
    std::cout << current->data << " ";
    current = current->next;
} while(current != start);

链表闭环

闭环定义

尾结点指向链表中任意随机结点形成的环状结构

闭环检测算法(快慢指针法)

实现原理

cpp
bool hasCycle(Node* head) {
    if(head == nullptr) return false;
    
    Node* slow = head;      // 慢指针(每次1步)
    Node* fast = head->next; // 快指针(每次2步)
    
    while(fast != nullptr && fast->next != nullptr) {
        if(slow == fast) return true;  // 指针相遇说明有环
        
        slow = slow->next;          // 慢指针走1步
        fast = fast->next->next;    // 快指针走2步
    }
    return false;  // 快指针遇到空说明无环
}

算法特性

  1. 时间复杂度:O(n)
  2. 空间复杂度:O(1)
  3. 有环判定:快慢指针相遇
  4. 无环判定:快指针遇到nullptr

作业

完成所有链表数据结构相关作业,包括:

  1. 带头结点的单链表实现
  2. 循环单链表实现
  3. 循环双链表实现
  4. 链表闭环检测算法
  5. 完善链表模板类封装

知识如风,常伴吾身