C++实现一个简化版的 list 容器,包含主要功能:
双向链表节点结构
cpp
template <typename T>
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) {}
};
List 类实现
cpp
#include <iostream>
#include <initializer_list>
template <typename T>
class List {
private:
struct Node {
T data;
Node* prev;
Node* next;
Node(const T& val = T(), Node* p = nullptr, Node* n = nullptr)
: data(val), prev(p), next(n) {}
};
Node* head; // 头节点(哨兵节点)
Node* tail; // 尾节点(哨兵节点)
size_t length; // 元素个数
public:
// 迭代器类
class iterator {
private:
Node* current;
public:
iterator(Node* node = nullptr) : current(node) {}
T& operator*() { return current->data; }
const T& operator*() const { return current->data; }
T* operator->() { return ¤t->data; }
const T* operator->() const { return ¤t->data; }
iterator& operator++() { // 前置++
current = current->next;
return *this;
}
iterator operator++(int) { // 后置++
iterator temp = *this;
current = current->next;
return temp;
}
iterator& operator--() { // 前置--
current = current->prev;
return *this;
}
iterator operator--(int) { // 后置--
iterator temp = *this;
current = current->prev;
return temp;
}
bool operator==(const iterator& other) const {
return current == other.current;
}
bool operator!=(const iterator& other) const {
return current != other.current;
}
friend class List<T>;
};
// 构造函数
List() : length(0) {
// 创建哨兵节点
head = new Node();
tail = new Node();
head->next = tail;
tail->prev = head;
}
List(std::initializer_list<T> init) : List() {
for (const auto& val : init) {
push_back(val);
}
}
// 拷贝构造函数
List(const List& other) : List() {
for (auto it = other.begin(); it != other.end(); ++it) {
push_back(*it);
}
}
// 移动构造函数
List(List&& other) noexcept
: head(other.head), tail(other.tail), length(other.length) {
other.head = nullptr;
other.tail = nullptr;
other.length = 0;
}
// 析构函数
~List() {
clear();
delete head;
delete tail;
}
// 拷贝赋值运算符
List& operator=(const List& other) {
if (this != &other) {
clear();
for (auto it = other.begin(); it != other.end(); ++it) {
push_back(*it);
}
}
return *this;
}
// 移动赋值运算符
List& operator=(List&& other) noexcept {
if (this != &other) {
clear();
delete head;
delete tail;
head = other.head;
tail = other.tail;
length = other.length;
other.head = nullptr;
other.tail = nullptr;
other.length = 0;
}
return *this;
}
// 容量操作
size_t size() const { return length; }
bool empty() const { return length == 0; }
// 元素访问
T& front() {
if (empty()) throw std::out_of_range("List is empty");
return head->next->data;
}
const T& front() const {
if (empty()) throw std::out_of_range("List is empty");
return head->next->data;
}
T& back() {
if (empty()) throw std::out_of_range("List is empty");
return tail->prev->data;
}
const T& back() const {
if (empty()) throw std::out_of_range("List is empty");
return tail->prev->data;
}
// 修改操作
void push_front(const T& val) {
insert(begin(), val);
}
void push_back(const T& val) {
insert(end(), val);
}
void pop_front() {
if (empty()) return;
erase(begin());
}
void pop_back() {
if (empty()) return;
iterator it = end();
--it;
erase(it);
}
// 插入操作
iterator insert(iterator pos, const T& val) {
Node* node = pos.current;
Node* newNode = new Node(val, node->prev, node);
node->prev->next = newNode;
node->prev = newNode;
++length;
return iterator(newNode);
}
// 删除操作
iterator erase(iterator pos) {
if (pos == end()) return end();
Node* node = pos.current;
Node* nextNode = node->next;
node->prev->next = node->next;
node->next->prev = node->prev;
delete node;
--length;
return iterator(nextNode);
}
iterator erase(iterator first, iterator last) {
while (first != last) {
first = erase(first);
}
return last;
}
void clear() {
erase(begin(), end());
}
// 迭代器
iterator begin() { return iterator(head->next); }
iterator end() { return iterator(tail); }
// const 迭代器
class const_iterator {
private:
const Node* current;
public:
const_iterator(const Node* node = nullptr) : current(node) {}
const T& operator*() const { return current->data; }
const T* operator->() const { return ¤t->data; }
const_iterator& operator++() {
current = current->next;
return *this;
}
const_iterator operator++(int) {
const_iterator temp = *this;
current = current->next;
return temp;
}
bool operator==(const const_iterator& other) const {
return current == other.current;
}
bool operator!=(const const_iterator& other) const {
return current != other.current;
}
};
const_iterator begin() const { return const_iterator(head->next); }
const_iterator end() const { return const_iterator(tail); }
// 其他操作
void reverse() {
if (length <= 1) return;
Node* current = head->next;
while (current != tail) {
std::swap(current->prev, current->next);
current = current->prev; // 注意:这里已经交换了prev和next
}
std::swap(head->next, tail->prev);
head->next->prev = head;
tail->prev->next = tail;
}
void remove(const T& val) {
iterator it = begin();
while (it != end()) {
if (*it == val) {
it = erase(it);
} else {
++it;
}
}
}
template<typename Predicate>
void remove_if(Predicate pred) {
iterator it = begin();
while (it != end()) {
if (pred(*it)) {
it = erase(it);
} else {
++it;
}
}
}
void unique() {
if (length <= 1) return;
iterator current = begin();
iterator next = current;
++next;
while (next != end()) {
if (*current == *next) {
next = erase(next);
} else {
current = next;
++next;
}
}
}
};
测试示例
cpp
int main() {
// 创建列表
List<int> lst = {1, 2, 3, 4, 5};
// 测试基本操作
std::cout << "Original list: ";
for (auto it = lst.begin(); it != lst.end(); ++it) {
std::cout << *it << " ";
}
std::cout << std::endl;
// 添加元素
lst.push_front(0);
lst.push_back(6);
std::cout << "After push: ";
for (auto val : lst) {
std::cout << val << " ";
}
std::cout << std::endl;
// 删除元素
lst.pop_front();
lst.pop_back();
std::cout << "After pop: ";
for (auto val : lst) {
std::cout << val << " ";
}
std::cout << std::endl;
// 插入和删除
auto it = lst.begin();
++it; ++it;
lst.insert(it, 99);
it = lst.begin();
++it;
lst.erase(it);
std::cout << "After insert/erase: ";
for (auto val : lst) {
std::cout << val << " ";
}
std::cout << std::endl;
// 反转
lst.reverse();
std::cout << "After reverse: ";
for (auto val : lst) {
std::cout << val << " ";
}
std::cout << std::endl;
// 移除特定值
lst.push_back(3);
lst.push_back(3);
lst.remove(3);
std::cout << "After remove(3): ";
for (auto val : lst) {
std::cout << val << " ";
}
std::cout << std::endl;
return 0;
}
实现特点:
- 哨兵节点设计:
· head 和 tail 作为边界标记
· 简化边界条件处理 - 内存管理:
· 遵循RAII原则
· 正确释放所有节点内存 - 迭代器支持:
· 支持前向和后向遍历
· 实现const迭代器 - 主要操作:
· push_front/push_back: O(1)
· pop_front/pop_back: O(1)
· insert/erase (已知位置): O(1)
· size/empty: O(1) - 异常安全:
· 基础版本提供基本异常安全保证
这只是一个简化的模拟版本,完整的STL list还需要实现反向迭代器、allocator支持、异常安全保证等更多功能。