list详解
概念
list的底层其实是一个双向循环链表,因此他不支持随机访问,但是在插入和删除上的效率很高,但是排序效率会低一些
使用
1,初始化
尾插:push_back
尾删:pop_back
头插:push_front
头删:pop_front
获取头部和尾部元素的引用
如果修改通过front和back的返回值,list内部的元素也会被修改
迭代器:(迭代器是一个类似于指针的东西,可以通过解引用去访问里面的数据,改变迭代器的数据同时也会改变容器内的数据)
1,正向迭代器(begin,end)
使用迭代器遍历
2,反向迭代器(rbegin,rend)
注意:反向迭代器的rbegin是返回最后一个元素的位置,如果向往前遍历,不是用–去操作,而是++,同样rend如果要往后遍历不是用++,而是用–
获取有效元素个数:size
在指定位置之前插入数据:insert
删除指定位置数据:erase
删除指定数据:remove
排序:sort
清空所有数据和判空:empty
交换两个list的数据:swap
迭代器失效问题
首先我们来看lt中的数据:
现在it指向第一个数据,然后把1删除掉:
在删除1后,第一个元素就变成了2,那么此时迭代器it是指向2,还是失效了?
来验证一下:
可以看到,直接报错,因为list是一个链表,所有删除数据后,第二个数据到第一的位置,但是迭代器记录的是第一个位置的地址,1被删除后,开辟的空间也被释放掉了,因此迭代器会失效
但是erase函数有一个返回值,在使用迭代器作为参数删除一个数据后,会返回这个数据的下一位置的迭代器
如果是删除最后一个数据,返回的是什么呢?
答案是返回最后一个元素的下一个位置,但是这个位置没有数据,因此直接访问会报错,但是如果–这个迭代器就可以得到最后一个数据,删除最后一个数据6后,最后一个数据变成了5,我们来验证一下:
模拟实现
#pragma once
#include<iostream>
#include<list>
#include<assert.h>
#include"iterator.h"
using namespace std;
namespace ys
{
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>
struct __list_iterator
{
typedef list_node<T> node;
typedef __list_iterator self;
node* _node;
__list_iterator(node* n)
:_node(n)
{
}
Ref operator *()
{
return _node->_data;
}
T& operator ->()
{
return _node->_data;
}
bool operator !=(const self& x)
{
return _node != x._node;
}
bool operator ==(const self& x)
{
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->_prve;
return tmp;
}
};
//反向迭代器
cosnt迭代器
//template<class T>
//struct __list_const_iterator
//{
// typedef list_node<T> node;
// typedef __list_const_iterator self;
// node* _node;
// __list_const_iterator(node* n)
// :_node(n)
// {
// }
// const T& operator *()
// {
// return _node->_data;
// }
// bool operator !=(const self& x)
// {
// return _node != x._node;
// }
// bool operator ==(const self& x)
// {
// 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->_prve;
// return *this;
// }
// //后置--
// self& operator--(int)
// {
// self tmp = _node;
// _node = _node->_prve;
// return tmp;
// }
//};
template<class T>
class list
{
typedef list_node<T> node;
public:
typedef __list_iterator<T,T&, T*> iterator;
typedef __list_iterator<T,const T&,const T*> const_irerator;
typedef ys1::ReverseIterator<iterator, T&, T*> reverse_iterator;
//typedef __list_const_iterator<T> const_irerator;
//空初始化
void empty_init()
{
_head = new node;
_head->_next = _head;
_head->_prev = _head;
}
list()
{
empty_init();
}
//迭代器区间初始化
template <class Iterator>
list(Iterator first, Iterator last)
{
empty_init();
while (first != last)
{
push_back(*first);
first++;
}
}
//交换
void swap(list<T>& tmp)
{
std::swap(_head, tmp._head);
}
list(const list<T>& lt)
{
empty_init();
//创建一个list作为中间层交换
list<T> ptr(lt.begin(),lt.end());
swap(ptr);
}
list<T>& operator=(list<T> lt)
{
swap(lt);
return *this;
}
//析构
~list()
{
clear();
delete _head;
_head = nullptr;
}
//清空所有数据
void clear()
{
iterator i = begin();
while (i != end())
{
erase(i++);
}
}
//迭代器
iterator begin()
{
/*iterator it(_head->_next);
return it;*/
return iterator(_head->_next);
}
iterator end()
{
return iterator(_head);
}
//cosnt迭代器
const_irerator cbegin() const
{
/*iterator it(_head->_next);
return it;*/
return const_irerator(_head->_next);
}
const_irerator cend() const
{
return const_irerator(_head);
}
//反向迭代器
reverse_iterator rbegin()
{
return reverse_iterator(end());
}
reverse_iterator rend()
{
return reverse_iterator(begin());
}
void push_back(const T& val)
{
//找到尾部节点
node* x = _head->_prev;
//创建新节点
node* ptr = new node;
ptr->_data = val;
x->_next = ptr;
ptr->_prev = x;
ptr->_next = _head;
_head->_prev = ptr;
}
//使用迭代器插入
void insert(iterator pos, const T& x)
{
node* prve = pos._node->_prev;
node* nod = pos._node;
node* ptr = new node(x);
prve->_next = ptr;
ptr->_prev = prve;
ptr->_next = nod;
nod->_prev = ptr;
}
//迭代器删除
iterator erase(iterator pos)
{
assert(pos != end());
node* prve = pos._node->_prev;
node* next = pos._node->_next;
prve->_next = next;
next->_prev = prve;
delete pos._node;
return iterator(next);
}
//头删
void pop_front()
{
erase(begin());
}
//尾删
void pop_back()
{
erase(end()--);
}
//头插
void push_front(const T& x)
{
insert(begin(),x);
}
private:
node* _head;
}
;
}
//迭代器:
#pragma once
namespace ys1
{
template<class iterator,class Ref, class Ptr>
struct ReverseIterator
{
typedef ReverseIterator<iterator, Ref, Ptr> Self;
iterator _cur;
ReverseIterator(iterator it)
:_cur(it)
{
}
Ref operator*()
{
iterator tmp = _cur;
--tmp;
return *tmp;
}
Self& operator++()
{
--_cur;
return *this;
}
Self& operator--()
{
++_cur;
return *this;
}
bool operator!=(const Self& s)
{
return _cur != s._cur;
}
};
}