目录
insert && push_back && push_front
erase && pop_back && pop_front
1.list注意事项:
1.list允许在任意位置常数时间O(1)插入删除,是带头双向循环列表
2.list的insert不会造成迭代器失效,只改变链接关系;erase造成迭代器失效,需要接收返回值(指向下一个节点)
3.begin在哨兵位next,end在哨兵位
4.list新增Operations
splice:把链表数据转移到另一个链表中
remove:等于find+erase,删除某个元素全部数据
remove_if:配合仿函数条件删除
unique:去重,前提排序
merge:两个链表归并到一起,取小的尾插
sort归并:仅支持list,算法库sort前提要求物理空间连续(快排三数取中)
reverse: 逆置
2. list迭代器框架
list_node
1.节点值_val,指向前一个节点的指针_prev,指向后一个节点的指针_next
2.构造函数初始化
__list_iterator
1.拿到对应结点,进行++迭代器操作
namespace Mylist
{
template<class T>
struct list_node
{
T _data;
list_node<T>* _next;
list_node<T>* _prev;
list_node(const T& x = T())//提供缺省值
:_data(x)
,_next(nullptr)
,_prev(nullptr)
{}
};
template<class T>
struct __list_iterator//提供一个节点,进行迭代器操作
{
typedef list_node<T> Node;
typedef __list_iterator<T> iterator;
Node* _node;
__list_iterator(Node* node)//构造函数
:_node(node)
{}
//...
iterator operator++()
{}
};
template<class T>
class list
{
typedef list_node<T> Node;
public:
typedef __list_iterator<T> iterator;
iterator begin()
{
return iterator(_head->_next);//匿名对象
}
iterator end()
{
return iterator(_head);//匿名对象
}
list()
{
_head = new Node;
_head->_next = _head;
_head->_prev = _head;
}
private:
Node* _head;//哨兵位头结点
};
}
由于节点的指针原生行为不满足迭代器定义,在这里,迭代器通过类来封装节点的指针重载运算符,如operator*、operator->、等
2.1 operator== != 运算符重载
bool operator!=(const iterator& it) const //判断节点指针是否相等
{
return _node != it._node;
}
bool operator==(const iterator& it) const //判断节点指针是否相等
{
return _node == it._node;
}
2.2 operator* 运算符重载
T& operator*()//可以修改
{
return _node->_data;
}
2.3 operator-> 运算符重载
编译器进行特殊处理,实际上是两个箭头
T& operator->()
{
return &(operator*());
}
2.4 拷贝构造
range(3):迭代器区间构造
用模板迭代器区间构造,好处是可以用任意类型迭代器区间来构造
void empty_init()//创建并初始化哨兵位头结点
{
_head = new Node;
_head->_next = _head;
_head->_prev = _head;
}
list()
{
empty_init();
}
template <class InputIterator>
list(InputIterator first, InputIterator last)
{
empty_init();//需要哨兵位头结点初始化,否则崩溃
while (first != last)
{
push_back