目录
为了更好的学会使用list和了解list的底层结构,我对list的一些常用接口进行了一个模拟实现。
准备工作:
编写的list由三个类组成,结点类(_list_node),迭代器类(_iterator)和list类(_list)
为什么需要这三个类?
1. 首先说明list底层是一个带头双向循环链表,是由一个一个的结点组成的,所以需要一个结点类。
2.由于链表不能进行下标访问,迭代时需要用到迭代器进行访问,并且有的函数参数需要迭代器作为参数,所以需要一个迭代器类。
1.结点类
由于list是带头双向循环链表,结点类中需要包含两个指针和一个值来保存数据。一个指针保存前一个结点地址,一个指针保存下一个结点地址。
2.迭代器类
迭代器成员变量实际是一个结点的指针,只是将其封装起来变成一个类,里面重载了许多操作符函数,使其使用起来,像一个指针。
为了可任意得到const迭代器和普通迭代器,我们在其模板使用了三个参数。如果使用一个参数,就会需要再写一个const迭代器类。
怎么实现的const和普通迭代器共用一个模板呢?
3.list类
list类的成员变量也是一个结点指针,并且是头节点的指针。
3.1 begin()和end()
3.2拷贝构造和赋值操作符重载
4. 完整代码
#include<iostream>
#include<assert.h>
using namespace std;
namespace my{
//结点信息
template<class T>
struct __list_node{
//构造函数
__list_node(const T& val = T())
:_next(nullptr)
, _prev(nullptr)
, _val(val)
{}
//结点成员变量
__list_node* _prev;
__list_node* _next;
T _val;
};
//迭代器
//为了同时实现iterator和const_iterator,模板含有三个变量
template<class T, class Ref, class Ptr>
struct _iterator{
typedef _iterator<T, Ref, Ptr> Self;
typedef __list_node<T> Node;
//成员变量
Node* _node;
_iterator(Node* node=nullptr)
:_node(node)
{}
_iterator(const Self& it)
:_node(it._node)
{}
Ref operator*(){
return _node->_val;
}
Ptr operator->(){
return &_node->_val;
}
bool operator==(const _iterator& x)const{
return _node == x._node;
}
bool operator!=(const _iterator& x)const{
return _node != x._node;
}
//前置++
Self& operator++(){
_node = _node->_next;
return *this;
}
//后置++
Self operator++(int){
Self tmp(_node);
_node = _node->_next;
return tmp;
}
//前置--
Self& operator--(){
_node = _node->_prev;
return *this;
}
//后置--
Self operator--(int){
Self tmp(_node);
_node = _node->_prev;
return tmp;
}
};
template<class T>
class _list{
public:
//const迭代器
typedef _iterator<T, const T&, const T*> const_iterator;
//普通迭代器
typedef _iterator<T, T&, T*> iterator;
typedef __list_node<T> Node;
public:
//构造函数因为要构建对象,所以要给头节点动态申请空间
_list(){
_head = new Node;
_head->_next = _head;
_head->_prev = _head;
}
_list(int n, const T& val){
_head = new Node;
_head->_next = _head;
_head->_prev = _head;
while (n){
push_back(val);
n--;
}
}
template<class inputiterator>
_list(inputiterator start, inputiterator end){
_head = new Node;
_head->_next = _head;
_head->_prev = _head;
while (start != end){
push_back(*start);
start++;
}
}
_list(const _list<T>& lt){
_head = new Node;
_head->_next = _head;
_head->_prev = _head;
const_iterator it = lt.begin();
while (it != lt.end()){
push_back(*it);
it++;
}
}
~_list(){
//先把结点删了,再删头节点
clear();
delete _head;
_head = nullptr;
}
//返回迭代器开始和结尾。写画图
//不能直接返回_head->next,这个不是迭代器类型
iterator begin(){
return iterator(_head->_next);
//return _head->_next;
}
iterator end(){
return iterator(_head);
}
const_iterator begin()const{
return const_iterator(_head->_next);
}
const_iterator end()const{
return const_iterator(_head);
}
_list<T>& operator=(_list<T>& lt){
//先将结点清楚,剩下一个头节点
clear();
//拷贝构造一个
_list<T> tmp(lt);
swap(_head, tmp._head);
return *this;
}
void clear(){
iterator it = begin();
while (it != end()){
erase(it++);
//迭代器失效
//it++;
}
}
void push_back(const T& val){
//Node* tail = _head->_prev;
//创建一个新节点
//Node* newnode = new Node(val);
//tail->_next = newnode;
//newnode->_next = _head;
//newnode->_prev = tail;
//_head->_prev = newnode;
//传迭代器参数
insert(end(), val);
}
void pop_back(){
erase(end()--);
}
void push_front(const T& val){
insert(begin(), val);
}
void pop_front(){
erase(begin());
}
iterator insert(iterator pos, const T& val){
//拿到pos里的结点
Node* cur = pos._node;
Node* newnode = new Node(val);
Node* prev = cur->_prev;
prev->_next = newnode;
newnode->_prev = prev;
newnode->_next = cur;
cur->_prev = newnode;
//返回迭代器,用迭代器构造一个
return iterator(newnode);
}
iterator erase(iterator pos){
assert(pos != end());
Node* cur = pos._node;
Node* next = cur->_next;
Node* prev = cur->_prev;
prev->_next = next;
next->_prev = prev;
delete cur;
return iterator(next);
}
size_t size(){
size_t len = 0;
for (auto c : *this){
len++;
}
return len;
}
bool empty(){
return _head->_next == _head;
}
private:
Node* _head;
};
};