List是由数据结构中的双向链表实现的可以高效地支持任意地方的删除和插入;内存空间可以是不连续的,只能通过指针来进行数据的访问,使得它的随机存取变的非常没有效率。
使用C++标准库里面的list时需加头文件
#include<list>
,且是属于std域,所以还应加上using namespace std
.
list的部分函数操作:
begin()
返回容器中第一个元素的迭代器,和front()不同,begin()返回的只是一个指向第一个元素的双向迭代器而已,如果容器为空返回的迭代器是无效的。
end()返回指向链表最后一个元素之后的迭代器
rbegin()返回逆向链表的第一个元素,即链表的最后一个数据
rend() 返回逆向链表的最后一个元素的下一个位置,即链表的第一个数据再往前的位
front() 返回链表的第一个元素
back() 返回链表的最后一个元素
empty()判断链表是否为空
size() 返回链表中实际元素的个数
max_size() 返回链表可能容纳的最大元素数量
clear() 清除链表中的所有元素
insert(pos,num) 在pos位置插入元素num
erase(pos)删除pos位置的元素
push_back(num)在末尾增加一个元素
pop_back() 删除末尾的元素
push_front(num) 在开始位置增加一个元素
pop_front()删除第一个元素
resize(n) 从新定义链表的长度,超出原始长度部分用0代替,小于原始部分删除
改变容器的大小,使得它能容纳n个元素
如果参数中的n,比当前容器的大小小,元素将会减少到这个容器的前n个,删除剩下的(resize函数会负责释放空间)
如果参数中的n,比当前容器的大小大,容器通过在尾部增加元素,使其达到n这个大小,如果val指定了参数,新的元素会被初始化为val。
operator==
operator!=
list的迭代器遍历方法:
List<int>::ConstIterator it = L.Begin();
while (it != L.End())
{
cout << *it << " ";
++it;
}
cout << endl;
list的简单实现:
#include<iostream>
#include<stdlib.h>
#include<assert.h>
using namespace std;
//节点结构类
template<class T>
struct ListNode
{
ListNode<T>* _prev;
ListNode<T>* _next;
T _data;
ListNode(const T& x)
:_data(x)
, _prev(NULL)
, _next(NULL)
{}
};
//迭代器类
template<class T,class Ref,class Ptr>
struct ListIterator
{
typedef ListNode<T> Node;
typedef ListIterator<T, Ref, Ptr> Self;
ListIterator(Node* node)
:_node(node)
{}
Ref operator*()
{
return _node->_data;
}
Ptr operator->()
{
return &(_node->_data);
}
Self& operator++()
{
_node = _node->_next;
return *this;
}
Self operator++(int)
{
Self ret(*this);
_node = _node->_next;
return ret;
}
Self& operator--()
{
_node = _node->_prev;
return *this;
}
Self operator--(int)
{
Self ret(*this);
_node = _node->_prev;
return ret;
}
bool operator != (const Self& t)
{
return _node != t._node;
}
bool operator == (const Self& t)
{
return _node == t._node;
}
Node* _node;
};
//List类(有头双向链表)
template<class T>
class List
{
public:
typedef ListNode<T> Node;
typedef ListIterator<T, T&, T*> Iterator;
typedef ListIterator<T, const T&, const T*> ConstIterator;
List()
:_head(new Node(T()))
{
_head->_next = _head;
_head->_prev = _head;
}
Iterator Begin()
{
return Iterator(_head->_next);
}
ConstIterator Begin() const
{
return ConstIterator(_head->_next);
}
Iterator End()
{
return Iterator(_head);
}
ConstIterator End() const
{
return ConstIterator(_head);
}
void PushBack(const T& x)
{
Node* NewNode = new Node(x);
Node* tail = _head->_prev;
tail->_next = NewNode;
NewNode->_prev = tail;
_head->_prev = NewNode;
NewNode->_next = _head;
}
void PopBack()
{
if (_head->_next == _head)
{
return;
}
else
{
Node* cur = _head;
while (cur->_next->_next!=_head)
{
cur = cur->_next;
}
Node* tail = cur;
cur->_next = NULL;
tail->_next = _head;
_head->_prev = tail;
}
}
void PushFront(const T& x)
{
Node* NewNode = new Node(x);
if (_head->_next == _head)
{
_head->_next = NewNode;
NewNode->_prev = _head;
_head->_prev = NewNode;
NewNode->_next = _head;
}
else
{
Node* cur = _head->_next;
_head->_next = NewNode;
NewNode->_prev = _head;
NewNode->_next = cur;
cur->_prev = NewNode;
}
}
void PopFront()
{
if (_head->_next == _head)
{
return;
}
else
{
Node* cur = _head->_next->_next;
_head->_next = cur;
cur->_prev = _head;
}
}
void Insert(Iterator pos, const T& x)
{
Node* cur = pos._node;
Node* prev = cur->_prev;
Node* NewNode = new Node(x);
prev->_next = NewNode;
NewNode->_next = cur;
cur->_prev = NewNode;
NewNode->_prev = prev;
}
Iterator Erase(Iterator& pos)
{
assert(pos != End());
Node* prev = pos._node->_prev;
Node* next = pos._node->_next;
prev->_next = next;
next->_prev = prev;
delete pos._node;
pos = prev;
return next;//防止迭代器失效
}
private:
Node* _head;
};
void Print(const List<int>& L)
{
List<int>::ConstIterator it = L.Begin();
while (it != L.End())
{
cout << *it << " ";
++it;
}
cout << endl;
}
int main()
{
List<int> L;
L.PushBack(1);
L.PushBack(2);
L.PushBack(3);
L.PushBack(4);
/*L.PopBack();
L.PopBack();
L.PushFront(0);
L.PopFront();
*/
List<int>::Iterator pos = L.Begin();
L.Erase(pos);
L.Insert(pos, 8);
Print(L);
system("pause");
}