以下是从零开始实现 C++ List 容器的完整指南,包含节点类与迭代器实现:

1. 节点类 (ListNode)

链表的基础单元,包含数据和前后指针:

template <typename T>
struct ListNode {
    T data;         // 存储的数据
    ListNode* prev; // 前驱节点指针
    ListNode* next; // 后继节点指针

    // 构造函数
    explicit ListNode(const T& val = T())
        : data(val), prev(nullptr), next(nullptr) {}
};

2. 迭代器类 (ListIterator)

实现 STL 兼容的迭代器功能:

template <typename T>
class ListIterator {
public:
    using iterator_category = std::bidirectional_iterator_tag;
    using value_type = T;
    using difference_type = std::ptrdiff_t;
    using pointer = T*;
    using reference = T&;

    explicit ListIterator(ListNode<T>* node = nullptr) : current(node) {}

    // 解引用操作符
    reference operator*() const { 
        return current->data; 
    }

    // 成员访问操作符
    pointer operator->() const { 
        return &(current->data); 
    }

    // 前置++
    ListIterator& operator++() {
        current = current->next;
        return *this;
    }

    // 后置++
    ListIterator operator++(int) {
        ListIterator temp = *this;
        ++(*this);
        return temp;
    }

    // 前置--
    ListIterator& operator--() {
        current = current->prev;
        return *this;
    }

    // 后置--
    ListIterator operator--(int) {
        ListIterator temp = *this;
        --(*this);
        return temp;
    }

    // 比较操作符
    bool operator==(const ListIterator& other) const { 
        return current == other.current; 
    }
    
    bool operator!=(const ListIterator& other) const { 
        return !(*this == other); 
    }

private:
    ListNode<T>* current; // 当前节点指针
};

3. List 容器实现

整合节点和迭代器完成链表容器:

template <typename T>
class List {
public:
    using iterator = ListIterator<T>;
    
    // 构造函数
    List() : size_(0) {
        // 创建头尾哨兵节点
        head = new ListNode<T>();
        tail = new ListNode<T>();
        head->next = tail;
        tail->prev = head;
    }

    // 析构函数
    ~List() {
        clear();
        delete head;
        delete tail;
    }

    // 迭代器访问
    iterator begin() { return iterator(head->next); }
    iterator end() { return iterator(tail); }

    // 插入元素
    void push_back(const T& value) {
        insert(end(), value);
    }

    iterator insert(iterator pos, const T& value) {
        ListNode<T>* newNode = new ListNode<T>(value);
        ListNode<T>* current = pos.current;
        
        newNode->prev = current->prev;
        newNode->next = current;
        current->prev->next = newNode;
        current->prev = newNode;
        
        ++size_;
        return iterator(newNode);
    }

    // 删除元素
    void pop_back() {
        erase(--end());
    }

    iterator erase(iterator pos) {
        ListNode<T>* toDelete = pos.current;
        iterator nextIter(toDelete->next);
        
        toDelete->prev->next = toDelete->next;
        toDelete->next->prev = toDelete->prev;
        
        delete toDelete;
        --size_;
        return nextIter;
    }

    // 清空链表
    void clear() {
        while (begin() != end()) {
            erase(begin());
        }
    }

    // 容器大小
    size_t size() const { return size_; }
    bool empty() const { return size_ == 0; }

private:
    ListNode<T>* head;  // 头哨兵节点
    ListNode<T>* tail;  // 尾哨兵节点
    size_t size_;       // 元素数量
};

4. 使用示例

int main() {
    List<int> myList;
    
    // 添加元素
    myList.push_back(10);
    myList.push_back(20);
    myList.push_back(30);

    // 遍历输出
    for (auto it = myList.begin(); it != myList.end(); ++it) {
        std::cout << *it << " ";
    }
    // 输出: 10 20 30

    // 删除元素
    auto it = myList.begin();
    ++it; // 指向第二个元素
    myList.erase(it);

    // 使用范围for循环
    for (int val : myList) {
        std::cout << val << " ";
    }
    // 输出: 10 30
}

关键设计要点

  1. 哨兵节点技术:头尾哑节点简化边界条件处理
  2. 双向链表结构:支持双向遍历
  3. 迭代器分类:符合 std::bidirectional_iterator 要求
  4. 内存管理
    • 节点动态内存分配
    • 析构函数自动释放内存
  5. 时间复杂度
    • 插入/删除:$O(1)$
    • 遍历:$O(n)$

此实现遵循 STL 设计规范,可通过添加 const_iterator 和反向迭代器进一步扩展功能。

更多推荐