调试环境:vs2015+win10
在STL中list算是一种比较常见的容器了,这里参考了一下SGI STL实现版本
概述
list即链表,结构较为复杂,由每一个节点相互链接起来的一种数据结构,它的优点是插入删除快,空间利用效率高。
list的节点
在STL中list是一个带头指针的双向链表,其每个节点结构如下:
template <typename T>
struct ListNode {
typedef ListNode<T> Node;
Node* _prev;
Node* _next;
T _data;
};
list的迭代器
迭代器就是可以像指针一样操控list,但是它又不是一种一般的指针,它是一种智能指针。并且有能力像普通指针一样,可已进行递增、递减、取值、成员存取等操作,即迭代器必须具有前移、后移的功能。
在list中插入和接合操作是不会造成原有的list迭代器失效,在删除元素中只有被指向删除元素的迭代器失效,其他的迭代器不会受任何影响。
综上所述,迭代器的设计如下:
template<typename T,typename Ref,typename Ptr>//传三个参数就可以不用判断是否为const参数
struct ListIterator
{
//重定义迭代器名
typedef ListIterator<T, T&, T*> iterator;
typedef ListIterator<T, Ref, Ptr> self;
//重定义参数
typedef T value_type;
typedef Ptr pointer;
typedef Ref reference;
typedef ListNode<T> Node;
//结构体数据成员
Node* _node;
//构造函数
ListIterator() {}
ListIterator(Node* x)
:_node(x)
{}
//拷贝构造
ListIterator(const iterator& x)
:Node(x._node)
{}
//重载判断运算符
bool operator==(const self& x)const {
return _node == x._node;
}
bool operator!=(const self& x)const {
return _node != x._node;
}
//重载解引用运算符,返回值为引用
reference operator*()const {
return _node->_data;
}
//返回值为指针
pointer operator->()const {
return &(operator*());
}
//重载自加、自减函数
self& operator++() {
_node = _node->_next;
return *this;
}
self& operator++(int) {
self tmp = *this;
++*this;
return tmp;
}
self& operator--() {
_node = _node->_prev;
return *this;
}
self& operator--(int) {
self tmp = *this;
--*this;
return tmp;
}
};
list的数据结构
SGI list不仅是一个双向链表,而且还是一个环状双向链表,所以它只需要一个指针,便可以完整表现整个链表,所以其结构如下:
template<typename T/*,typename Alloc = alloc*/>
//这里应该写空间配置器,由于实现比较复杂,所以直接用类自己实现
class List {
public:
typedef ListNode<T> Node;
typedef ListIterator<T, T&, T*> iterator;
typedef Node value_type;
typedef Node* pointer;
typedef Node& reference;
//构造函数
List()
:_node(BuyNode(T()))
{
_node->_next = _node;
_node->_prev = _node;
}
//拷贝构造函数
List(const Node& x)
:_node(BuyNode(T()))
{
_node->_data = x;
_node->_next = _head;
_node->_prev = _head;
}
//赋值运算符重载
reference operator=(Node& node) {
if (this != &node) {
_node->_data = node._data;
_node->_next = node._next;
_node->_prev = node._prev;
}
}
//析构函数
~List() {
if (_node != NULL) {
Node* head = Begin()._node;
Node* tail = End()._node;
while (head != tail) {
Node* tmp = head;
head = head->_next;
delete tmp;
}
delete _node;
}
}
//返回list第一个节点
iterator Begin() {
return _node->_next;
}
//返回list最后一个节点的后一个地址,即list头指针
iterator End() {
return _node;
}
//判断list是否为空
bool Empty()const {
return _node->_next == _node;
}
//const版返回节点个数
size_t Size()const {
size_t count = 0;
iterator begin = Begin();
iterator end = End();
while (begin != end) {
++count;
++begin;
}
return count;
}
//返回list节点个数
size_t Size(){
size_t count = 0;
iterator begin = Begin();
iterator end = End();
while (begin != end) {
++count;
++begin;
}
return count;
}
//返回第一个节点的值引用
reference Front() {
return *(Begin()._node);
}
//返回最后一个节点值的引用
reference Back() {
return *((--End())._node);
}
//在迭代器之前插入一个值为x的节点
iterator Insert(iterator position, const T& x) {
Node* tmp = new Node(x);
tmp->_next = position._node;
tmp->_prev = position._node->_prev;
position._node->_prev->_next = tmp;
position._node->_prev = tmp;
return position;
}
//头增
void PushFront(const T& x) {
Insert(Begin(), x);
}
//尾增
void PushBack(const T& x) {
Insert(End(), x);
}
//删除迭代器所指向的节点
iterator Erase(iterator position) {
Node* next = position._node->_next;
Node* prev = position._node->_prev;
prev->_next = next;
next->_prev = prev;
delete position._node;
return iterator(next);
}
//头删
void PopFront() {
Erase(Begin());
}
//尾删
void PopBack() {
Erase(--End());
}
//打印list
void Print() {
iterator head = Begin();
iterator tail = End();
while (head._node != tail._node) {
cout << head._node->_data << " ";
head._node = head._node->_next;
}
cout << endl;
}
//在first和last之间查找值为x的迭代器
iterator Find(iterator first, iterator last, const T& x) {
for (; first != last; first++) if (*first == x) break;
return first;
}
protected:
Node* BuyNode(const T& x) { //申请节点
return (new Node(x));
}
protected:
Node* _node;
};