欢迎光临
我们一直在努力

手把手实现C++STL list容器

好的,我们来逐步模拟实现一个简化版的 C++ STL list 容器。我们将从最基础的节点结构开始,构建双向链表,然后封装成具备常用接口的容器类。

1. 节点结构 (ListNode)

链表的基本单位是节点。每个节点包含:

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

    // 构造函数
    ListNode(const T& val = T(), ListNode<T>* p = nullptr, ListNode<T>* n = nullptr)
    : data(val), prev(p), next(n) {}
    };

    2. 链表基础结构 (List)

    List 类需要管理链表的头尾,并记录元素个数。为了方便操作(如 begin() 和 end()),通常会使用一个哨兵节点(dummy node)来简化边界条件的处理。这个哨兵节点不存储有效数据,其 next 指向第一个有效节点,prev 指向最后一个有效节点,自身形成一个循环。

    template<typename T>
    class List {
    private:
    ListNode<T>* dummy; // 哨兵节点
    size_t count; // 元素个数

    public:
    // 构造函数
    List() : count(0) {
    dummy = new ListNode<T>(); // 创建哨兵节点
    dummy->next = dummy; // 初始化时,自己指向自己
    dummy->prev = dummy;
    }

    // 析构函数 – 释放所有节点
    ~List() {
    clear(); // 清空有效节点
    delete dummy; // 删除哨兵节点
    }

    // 清空链表
    void clear() {
    ListNode<T>* cur = dummy->next;
    while (cur != dummy) { // 遍历到哨兵节点停止
    ListNode<T>* next = cur->next;
    delete cur;
    cur = next;
    }
    dummy->next = dummy; // 重置哨兵节点指向
    dummy->prev = dummy;
    count = 0;
    }

    // … 其他成员函数将在下面实现
    };

    http://my.tv.sohu.com/us/441086388/698251347.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTM0Ny5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251553.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTU1My5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251264.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTI2NC5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251562.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTU2Mi5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251604.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTYwNC5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251283.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTI4My5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251587.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTU4Ny5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251591.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTU5MS5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251620.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTYyMC5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251706.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTcwNi5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251657.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTY1Ny5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251812.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTgxMi5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251662.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTY2Mi5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251921.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTkyMS5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251667.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTY2Ny5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251818.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTgxOC5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251671.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTY3MS5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251676.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTY3Ni5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251739.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTczOS5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251682.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTY4Mi5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251831.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTgzMS5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251688.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTY4OC5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251695.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTY5NS5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698252002.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MjAwMi5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698252005.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MjAwNS5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251950.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTk1MC5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251956.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTk1Ni5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251847.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTg0Ny5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698252023.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MjAyMy5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251856.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTg1Ni5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698252042.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MjA0Mi5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251872.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTg3Mi5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698252054.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MjA1NC5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698252106.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MjEwNi5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251884.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTg4NC5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251891.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTg5MS5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251895.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTg5NS5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698252125.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MjEyNS5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698252079.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MjA3OS5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698252309.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MjMwOS5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698252238.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MjIzOC5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698252324.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MjMyNC5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698252095.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MjA5NS5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698252334.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MjMzNC5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698252154.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MjE1NC5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698252160.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MjE2MC5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698252343.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MjM0My5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698252413.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MjQxMy5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698252178.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MjE3OC5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698252265.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MjI2NS5zaHRtbA==.html  

    3. 迭代器 (Iterator)

    STL 容器的精髓在于迭代器。我们需要实现一个双向迭代器,支持 ++, –, *, ->, ==, != 等操作。迭代器本质上是对节点指针的封装。

    template<typename T>
    class List {
    // … 前面的代码

    public:
    // 迭代器类 (嵌套在 List 内部)
    class Iterator {
    private:
    ListNode<T>* ptr; // 指向当前节点的指针

    public:
    Iterator(ListNode<T>* p = nullptr) : ptr(p) {}

    // 解引用操作符 (*)
    T& operator*() const {
    return ptr->data;
    }

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

    // 前缀 ++
    Iterator& operator++() {
    ptr = ptr->next;
    return *this;
    }

    // 后缀 ++ (需要 int 参数占位)
    Iterator operator++(int) {
    Iterator old = *this;
    ++(*this);
    return old;
    }

    // 前缀 —
    Iterator& operator–() {
    ptr = ptr->prev;
    return *this;
    }

    // 后缀 —
    Iterator operator–(int) {
    Iterator old = *this;
    –(*this);
    return old;
    }

    // 相等比较
    bool operator==(const Iterator& other) const {
    return ptr == other.ptr;
    }

    // 不等比较
    bool operator!=(const Iterator& other) const {
    return ptr != other.ptr;
    }
    };

    // 获取指向第一个元素的迭代器
    Iterator begin() const {
    return Iterator(dummy->next);
    }

    // 获取尾后迭代器 (指向哨兵节点)
    Iterator end() const {
    return Iterator(dummy);
    }

    // … 其他成员函数
    };

    http://my.tv.sohu.com/us/441086388/698251347.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTM0Ny5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251553.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTU1My5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251264.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTI2NC5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251562.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTU2Mi5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251604.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTYwNC5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251283.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTI4My5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251587.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTU4Ny5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251591.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTU5MS5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251620.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTYyMC5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251706.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTcwNi5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251657.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTY1Ny5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251812.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTgxMi5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251662.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTY2Mi5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251921.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTkyMS5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251667.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTY2Ny5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251818.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTgxOC5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251671.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTY3MS5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251676.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTY3Ni5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251739.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTczOS5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251682.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTY4Mi5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251831.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTgzMS5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251688.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTY4OC5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251695.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTY5NS5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698252002.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MjAwMi5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698252005.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MjAwNS5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251950.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTk1MC5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251956.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTk1Ni5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251847.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTg0Ny5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698252023.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MjAyMy5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251856.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTg1Ni5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698252042.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MjA0Mi5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251872.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTg3Mi5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698252054.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MjA1NC5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698252106.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MjEwNi5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251884.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTg4NC5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251891.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTg5MS5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698251895.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MTg5NS5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698252125.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MjEyNS5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698252079.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MjA3OS5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698252309.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MjMwOS5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698252238.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MjIzOC5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698252324.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MjMyNC5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698252095.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MjA5NS5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698252334.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MjMzNC5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698252154.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MjE1NC5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698252160.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MjE2MC5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698252343.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MjM0My5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698252413.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MjQxMy5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698252178.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MjE3OC5zaHRtbA==.html http://my.tv.sohu.com/us/441086388/698252265.shtml https://tv.sohu.com/v/dXMvNDQxMDg2Mzg4LzY5ODI1MjI2NS5zaHRtbA==.html  

    4. 核心功能实现

    现在利用节点、哨兵和迭代器,实现 list 的核心操作:插入、删除、访问等。

    push_back (尾部插入)

    void push_back(const T& value) {
    ListNode<T>* last = dummy->prev; // 当前最后一个有效节点
    ListNode<T>* newNode = new ListNode<T>(value, last, dummy); // 新节点,prev指最后节点,next指dummy
    last->next = newNode; // 原最后一个节点的next指向新节点
    dummy->prev = newNode; // dummy的prev指向新节点 (新节点成为最后一个)
    ++count;
    }

    push_front (头部插入)

    void push_front(const T& value) {
    ListNode<T>* first = dummy->next; // 当前第一个有效节点
    ListNode<T>* newNode = new ListNode<T>(value, dummy, first); // 新节点,prev指dummy,next指第一个节点
    dummy->next = newNode; // dummy的next指向新节点 (新节点成为第一个)
    first->prev = newNode; // 原第一个节点的prev指向新节点
    ++count;
    }

    insert (在迭代器位置前插入)

    Iterator insert(Iterator pos, const T& value) {
    ListNode<T>* currNode = pos.ptr; // 当前迭代器指向的节点
    ListNode<T>* prevNode = currNode->prev; // 当前节点的前一个节点

    ListNode<T>* newNode = new ListNode<T>(value, prevNode, currNode);
    prevNode->next = newNode;
    currNode->prev = newNode;

    ++count;
    return Iterator(newNode); // 返回指向新插入元素的迭代器
    }

    erase (删除迭代器指向的元素)

    Iterator erase(Iterator pos) {
    if (pos == end()) { // 不能删除尾后迭代器
    return end();
    }
    ListNode<T>* currNode = pos.ptr;
    ListNode<T>* prevNode = currNode->prev;
    ListNode<T>* nextNode = currNode->next;

    prevNode->next = nextNode;
    nextNode->prev = prevNode;

    Iterator nextIter(nextNode); // 记录下一个元素的迭代器
    delete currNode;
    –count;
    return nextIter; // 返回被删除元素的下一个元素的迭代器
    }

    size 和 empty

    size_t size() const {
    return count;
    }

    bool empty() const {
    return count == 0;
    }

    front 和 back (访问首尾元素)

    T& front() {
    return dummy->next->data; // 第一个有效节点的数据
    }

    const T& front() const {
    return dummy->next->data;
    }

    T& back() {
    return dummy->prev->data; // 最后一个有效节点的数据
    }

    const T& back() const {
    return dummy->prev->data;
    }

    5. 完整示例代码 (简化版)

    将以上部分组合起来:

    template<typename T>
    class List {
    private:
    struct ListNode {
    T data;
    ListNode* prev;
    ListNode* next;
    ListNode(const T& val = T(), ListNode* p = nullptr, ListNode* n = nullptr)
    : data(val), prev(p), next(n) {}
    };

    ListNode* dummy;
    size_t count;

    public:
    class Iterator {
    private:
    ListNode* ptr;
    public:
    Iterator(ListNode* p = nullptr) : ptr(p) {}
    T& operator*() const { return ptr->data; }
    T* operator->() const { return &(ptr->data); }
    Iterator& operator++() { ptr = ptr->next; return *this; }
    Iterator operator++(int) { Iterator old = *this; ++(*this); return old; }
    Iterator& operator–() { ptr = ptr->prev; return *this; }
    Iterator operator–(int) { Iterator old = *this; –(*this); return old; }
    bool operator==(const Iterator& other) const { return ptr == other.ptr; }
    bool operator!=(const Iterator& other) const { return ptr != other.ptr; }
    };

    List() : count(0) {
    dummy = new ListNode();
    dummy->next = dummy;
    dummy->prev = dummy;
    }

    ~List() {
    clear();
    delete dummy;
    }

    void clear() {
    ListNode* cur = dummy->next;
    while (cur != dummy) {
    ListNode* next = cur->next;
    delete cur;
    cur = next;
    }
    dummy->next = dummy;
    dummy->prev = dummy;
    count = 0;
    }

    Iterator begin() const { return Iterator(dummy->next); }
    Iterator end() const { return Iterator(dummy); }

    void push_back(const T& value) {
    ListNode* last = dummy->prev;
    ListNode* newNode = new ListNode(value, last, dummy);
    last->next = newNode;
    dummy->prev = newNode;
    ++count;
    }

    void push_front(const T& value) {
    ListNode* first = dummy->next;
    ListNode* newNode = new ListNode(value, dummy, first);
    dummy->next = newNode;
    first->prev = newNode;
    ++count;
    }

    Iterator insert(Iterator pos, const T& value) {
    ListNode* currNode = pos.ptr;
    ListNode* prevNode = currNode->prev;
    ListNode* newNode = new ListNode(value, prevNode, currNode);
    prevNode->next = newNode;
    currNode->prev = newNode;
    ++count;
    return Iterator(newNode);
    }

    Iterator erase(Iterator pos) {
    if (pos == end()) return end();
    ListNode* currNode = pos.ptr;
    ListNode* prevNode = currNode->prev;
    ListNode* nextNode = currNode->next;
    prevNode->next = nextNode;
    nextNode->prev = prevNode;
    Iterator nextIter(nextNode);
    delete currNode;
    –count;
    return nextIter;
    }

    size_t size() const { return count; }
    bool empty() const { return count == 0; }

    T& front() { return dummy->next->data; }
    const T& front() const { return dummy->next->data; }
    T& back() { return dummy->prev->data; }
    const T& back() const { return dummy->prev->data; }
    };

    总结

    这个简化版的 List 实现了 STL list 的核心功能:

  • 底层结构:基于带有哨兵节点的双向循环链表。
  • 节点管理:ListNode 封装数据和指针。
  • 迭代器:Iterator 类封装节点指针,提供类似指针的操作接口,使算法能透明地操作容器元素。
  • 容器接口:提供了 begin(), end(), push_back, push_front, insert, erase, size, empty, front, back 等常用接口。
  • 实际 STL 的实现更为复杂,涉及内存分配器 (allocator)、更完善的异常安全保证、类型萃取 (type traits)、const 迭代器、反向迭代器 (reverse_iterator) 等。但这个简化版清晰地展示了 list 从底层链表到容器封装的关键设计思想和实现路径。

    赞(0)
    未经允许不得转载:171主机测评 » 手把手实现C++STL list容器
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址