好的,我们来逐步模拟实现一个简化版的 C++ STL list 容器。我们将从最基础的节点结构开始,构建双向链表,然后封装成具备常用接口的容器类。
1. 节点结构 (ListNode)
链表的基本单位是节点。每个节点包含:
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 的核心功能:
实际 STL 的实现更为复杂,涉及内存分配器 (allocator)、更完善的异常安全保证、类型萃取 (type traits)、const 迭代器、反向迭代器 (reverse_iterator) 等。但这个简化版清晰地展示了 list 从底层链表到容器封装的关键设计思想和实现路径。




