2.3-STL库中list的模拟实现
2.3-STL库中list的模拟实现
list相比于其他的容器,更重要的是它较为复杂的迭代器。
为了能提供可直接运行的代码,接下来的内容在代码块中完成。
#pragma once
#include <iostream>
#include <algorithm>
namespace lst {
//节点
template<class T>
struct list_node {
list_node<T>* _next;
list_node<T>* _prev;
T _data;
list_node(const T& x = T()) : _next(nullptr), _prev(nullptr) , _data(x){}
};
// 封装迭代器
template<class T, class Ref, class Ptr> // 添加两个模板参数,分别支持引用和指针,实现 const 与非 const 的复用。
struct __list_iterator
{
typedef list_node<T> node;
typedef __list_iterator<T, Ref, Ptr> self;
node* _node;
__list_iterator(node* n) : _node(n){}
Ref operator*() {
return _node->_data;
}
self& operator++() {
_node = _node->_next;
return *this;
}
bool operator!=(const self& s) {
return _node != s._node;
}
bool operator==(const self& s) {
return _node == s._node;
}
Ptr operator->() {
return &_node->_data;
}
};
template<class T>
class list {
public:
typedef list_node<T> node;
typedef __list_iterator<T, T&, T*> iterator;
typedef __list_iterator<T, const T&, const T*> const_iterator;
// 空初始化
void empty_inite() { // 值得注意的是,对于 const 对象,依然可以调用此函数。因为 const 对象在初始化之前不具有 const 属性。
_head = new node;
_head->_next = _head;
_head->_prev = _head;
}
// 构造函数
list() {
empty_inite();
}
// 区间构造
template<class iterator>
list(iterator first, iterator last) {
empty_inite();
while (first != last) {
push_back(*first);
++first;
}
}
void swap(list<T>& tmp) {
std::swap(_head, tmp._head);
}
// 拷贝构造
list(const list<T>& it) {
empty_inite();
list<T> tmp(it.begin(), it.end())
swap(tmp);
}
//赋值重载
list<T>& operator=(list<T> it) { // 传值传参,获得深拷贝。
swap(it);
return *this;
}
~list() {
clear();
delete _head;
_head = nullptr;
}
void clear() {
iterator it = begin();
while (it != end()) {
it = erase(it);
}
}
void push_back(const T& x) {
node* tail = _head->_prev;
node* new_node = new node(x);
tail->_next = new_node;
new_node->_prev = tail;
new_node->_next = _head;
_head->_prev = new_node;
}
iterator begin() {
return iterator(_head->_next);
}
iterator end() {
return iterator(_head);
}
const_iterator begin() const{
return const_iterator(_head->_next);
}
const_iterator end() const{
return const_iterator(_head);
}
// 插入
void insert(iterator pos, T x) {
node* cur = pos._node;
node* prev = cur->_prev;
node* newnode = new node(x);
prev->_next = newnode;
newnode->_prev = prev;
newnode->_next = cur;
cur->_prev = newnode;
}
// 删除
iterator erase(iterator pos) {
node* next = pos._node->_next;
node* prev = pos._node->_prev;
prev->_next = next;
next->_prev = prev;
delete pos._node;
return iterator(next);
}
//此处略过头插,头删,尾删。
private:
node* _head;
};
template<class T>
void print_list(const list<T>& l) {
auto it = l.begin();
while (it != l.end()) {
std::cout << *it << " ";
++it;
}
std::cout << std::endl;
}
void test_list1() {
//尾插
list<int> l;
l.push_back(1);
l.push_back(2);
l.push_back(3);
l.push_back(4);
l.push_back(5);
// 迭代器。
list<int>::iterator it = l.begin();
while (it != l.end()) {
std::cout << *it << " ";
++it;
}
std::cout << std::endl;
// 范围for,只要名字起对了,范围for就天然可用了。
for(auto e : l) {
std::cout << e << " ";
}
std::cout << std::endl;
l.push_back(15);
// 测试const迭代器
print_list(l); // 1 2 3 4 5 15
}
void test_list2() {
list<int> l;
l.push_back(1);
l.push_back(1);
l.push_back(1);
l.push_back(2);
l.push_back(1);
l.push_back(1);
l.push_back(1);
for (auto e : l) {
std::cout << e << " ";
}
std::cout << std::endl;// 1 1 1 2 1 1 1
auto pos = l.begin();
++pos;
l.insert(pos, 20); // 1 20 1 1 2 1 1 1
for (auto e : l) {
std::cout << e << " ";
}
std::cout << std::endl;
l.erase(pos); // 1 20 1 2 1 1 1
for (auto e : l) {
std::cout << e << " ";
}
std::cout << std::endl;
//测试clear
l.clear();
std::cout << std::endl; // 啥也没有。
}
}