list容器底层是带头双向链表结构,可以在常数范围内在任意位置进行输入和删除,但不支持任意位置的随机访问(如不支持[ ]下标访问),下面介绍list容器的基本使用接口。
template < class T, class Alloc = allocator > class list;
构造
1.无参构造
list()
2.使用n个元素val进行构造
list(size_type n,const value_type& value = value_type());
3,拷贝构造
list(const list& x);
4.使用迭代器区间进行构造
list(InputIterator first, InputIterator last);
迭代器
1.正向迭代器
iterator begin();
const_iterator begin() const;
iterator end();
const_iterator end() const;
2.反向迭代器
reverse_iterator rbegin();
const_reverse_iterator rbegin() const;
reverse_iterator rend();
const_reverse_iterator rend() const;
容量
1.判断链表是否为空
bool empty() const;
2.获取链表中有效节点个数
size_type size() const;
3.修改容量大小
void resize (size_type n, value_type val = value_type());
访问
1.获取链表第一个节点的值的引用
reference front();
const_reference front() const;
2.获取链表最后一个节点的值的引用
reference back();
const_reference back() const;
修改
1.元素首插
void push_front (const value_type& val);
2.元素尾插
void push_back (const value_type& val);
3.在position位置插入值为val的元素
iterator insert (iterator position, const value_type& val);
void insert (iterator position, size_type n, const value_type& val);
template <class InputIterator>
void insert (iterator position, InputIterator first, InputIterator last);
//Notice that the range includes all the elements between first and last, including the element pointed by first but not the one pointed by last.
5.元素首删
void pop_front();
6.元素尾删
void pop_back();
7.删除position位置的元素
iterator erase (iterator position);
iterator erase (iterator first, iterator last);
//the range includes all the elements between first and last, including the element pointed by first but not the one pointed by last.
8.清空链表有效元素
void clear();
9.交换两个链表的所有元素
void swap (list& x);
需要注意的是,list在进行插入操作时,不需要移动数据,因此进行元素插入不会导致迭代器失效,但在进行元素删除时,指向删除元素的迭代器会失效,其他的并没有影响。
list具体使用可以查看相关文档:list
模拟实现
#include <assert.h>
#include <iostream>
using namespace std;
namespace roman {
// List的节点类
template <class T> struct ListNode {
ListNode(const T& val = T()) :
_val(val),
_next(nullptr),
_pre(nullptr)
{}
ListNode<T>* _pre;
ListNode<T>* _next;
T _val;
};
// List的迭代器类
template <class T, class Ref, class Ptr> class ListIterator {
template <class T> friend class list;
typedef ListNode<T>* PNode;
typedef ListIterator<T, Ref, Ptr> Self;
public:
ListIterator(PNode pNode = nullptr) : _pNode(pNode) {}
Ref operator*() { return _pNode->_val; }
Ptr operator->() { return &(_pNode->_val); }
Self& operator++() {
_pNode = _pNode->_next;
return *this;
}
Self operator++(int) {
Self tmp = *this;
_pNode = _pNode->_next;
return tmp;
}
Self& operator--() {
_pNode = _pNode->_pre;
return *this;
}
Self& operator--(int) {
Self tmp = *this;
_pNode = _pNode->_pre;
return tmp;
}
bool operator!=(const Self& l) { return _pNode != l._pNode; }
bool operator==(const Self& l) { return _pNode == l._pNode; }
private:
PNode _pNode;
};
// list类
template <class T>
class list {
typedef ListNode<T> Node;
typedef Node* pNode;
public:
typedef ListIterator<T, T&, T*> iterator;
typedef ListIterator<T, const T&, const T&> const_iterator;
public:
template <class T1>
friend ostream& operator<<(ostream& out, const list<T1>& l);
///////////////////////////////////////////////////////////////
// List的构造
list() : _phead(new Node) {
if (nullptr == _phead) {
perror("new");
return;
}
_phead->_next = _phead;
_phead->_pre = _phead;
}
list(int n, const T& value = T()) : _phead(new Node) {
if (nullptr == _phead) {
perror("new");
return;
}
_phead->_next = _phead;
_phead->_pre = _phead;
assert(n >= 0);
pNode tail = _phead->_pre;
while (n--) {
pNode node = new Node(value);
tail->_next = node;
node->_pre = tail;
node->_next = _phead;
_phead->_pre = node;
tail = node;
}
}
template <class Iterator>
list(Iterator first, Iterator last) : _phead(new Node) {
if (nullptr == _phead) {
perror("new");
return;
}
_phead->_next = _phead;
_phead->_pre = _phead;
pNode tail = _phead->_pre;
while (first != last) {
pNode node = new Node(first->_val);
tail->_next = node;
node->_pre = tail;
node->_next = _phead;
_phead->_pre = node;
tail = node;
++first;
}
}
list(const list<T>& l) : _phead(new Node) {
if (nullptr == _phead) {
perror("new");
return;
}
_phead->_next = _phead;
_phead->_pre = _phead;
pNode tail = _phead->_pre;
pNode copy_node = (l._phead)->_next;
while (copy_node != l._phead) {
pNode node = new Node(copy_node->_val);
tail->_next = node;
node->_pre = tail;
node->_next = _phead;
_phead->_pre = node;
tail = node;
copy_node = copy_node->_next;
}
}
list<T>& operator=(const list<T> l) {
std::swap(_phead->_next, (l._phead->_next));
return *this;
}
~list() {
pNode cur = _phead->_pre;
while (cur != _phead) {
cur = cur->_pre;
delete cur->_next;
}
delete _phead;
_phead = nullptr;
}
///////////////////////////////////////////////////////////////
// List Iterator
iterator begin() { return iterator(_phead->_next); }
iterator end() { return iterator(_phead); }
const_iterator begin() const { return const_iterator(_phead->_next); }
const_iterator end() const { return const_iterator(_phead); }
///////////////////////////////////////////////////////////////
// List Capacity
size_t size() const {
int length = 0;
pNode cur = _phead->_next;
while (cur != _phead) {
++length;
cur = cur->_next;
}
return length;
}
bool empty() const { return _phead == _phead->_next; }
////////////////////////////////////////////////////////////
// List Access
T& front() { return _phead->_next->_val; }
const T& front() const { return _phead->_next->_val; }
T& back() { return _phead->_pre->_val; }
const T& back() const { return _phead->_pre->_val; }
////////////////////////////////////////////////////////////
// List Modify
void push_back(const T& val) { insert(end(), val); }
void pop_back() { erase(--end()); }
void push_front(const T& val) { insert(begin(), val); }
void pop_front() { erase(begin()); }
// 在pos位置前插入值为val的节点
iterator insert(iterator pos, const T& val) {
pNode node = new Node(val);
(pos._pNode)->_pre->_next = node;
node->_pre = (pos._pNode->_pre);
node->_next = pos._pNode;
(pos._pNode)->_pre = node;
return iterator(node);
}
// 删除pos位置的节点,返回该节点的下一个位置
iterator erase(iterator pos) {
assert((pos._pNode) != _phead);
(pos._pNode)->_pre->_next = (pos._pNode)->_next;
(pos._pNode)->_next->_pre = pos._pNode->_pre;
pNode tmp = (pos._pNode)->_next;
delete pos._pNode;
return iterator(tmp);
}
void clear() {
pNode cur = _phead->_next;
pNode next = cur->_next;
while (cur != _phead) {
delete cur;
cur = next;
next = next->_next;
}
_phead->_next = _phead;
_phead->_pre = _phead;
}
void swap(list<T>& l) {
pNode head = _phead->_next;
pNode tail = _phead->_pre;
_phead->_next->_pre = l._phead;
_phead->_pre->_next = l._phead;
(l._phead)->_next->_pre = _phead;
(l._phead)->_pre->_next = _phead;
_phead->_next = (l._phead)->_next;
_phead->_pre = (l._phead)->_pre;
(l._phead)->_next = head;
(l._phead)->_pre = tail;
}
private:
pNode _phead;
};
template <class T1>
ostream& operator<<(ostream& out, const roman::list<T1>& l) {
roman::ListNode<T1>* tail = (l._phead)->_next;
while (tail != l._phead) {
out << (tail->_val) << ' ';
tail = tail->_next;
}
return out;
}
}; // namespace roman