list介绍
list模板类也是一个容器。list是由双向链表实现,每个节点存储一个元素。list支持前后两种移动方向。
list优势在于可以在任何位置上进行插入、删除,同时也可以双向迭代。
list与vector的区别
- list不支持随机访问
- list没有下标访问符[]和at()函数
- list没有提供容量,空间操作的函数,每个元素都有自己的内存。list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素。
- list的插入、删除不会影响迭代器的失效
list构造函数
list() | 构造空的 list |
---|---|
list(size) | 创建大小为 size 的对象 |
list(size , value) | 创建大小为 size 的对象,每个元素的初始值都为 value |
list(const list& l) | 拷贝构造 |
list(first , end) | 用[first , end)区间的元素创建 list |
元素的赋值
push_front() | 在容器的头部插入新的元素 |
---|---|
push_back() | 在容器的尾部插入新的元素 |
pop_front() | 删除头元素 |
pop_back() | 删除尾元素 |
//函数原型
void push_front(const T& x);
void push_back(const T& x);
void pop_front();
void pop_back();
容器的容量
resize()、size()、max_size()作用于vector容器中的作用类似。
max_size()为容器最大
特殊函数
merge(),将2个list对象合并成文一个list对象,合并后的容器中的元素是按照升序排列。
sort(),用于list类型容器中的元素进行排序,默认的排序方式为从小到大。
void sort();
void sort(greater<T> x);//从大到小排序
remove(),不需要指定位置,只需要告诉删除元素的值,就可以直接删除相应的元素。
unique(),移除相邻重复的元素
l1.unique(); //删除相邻重复的元素
l2.unique(Pred);//仅保留与第一个元素相等的元素
如果用unique()函数,删除重复的元素时,应该先给对象进行排序。
reverse(),翻转字符串
#include<iostream>
using namespace std;
namespace Bai
{
template<class T>
class ListNode
{
public:
ListNode(const T& value = T())
:val (value)
,_pnext(nullptr)
,_prev(nullptr)
{}
T val;
ListNode<T>* _pnext;
ListNode<T>* _prev;
};
template<class T,class Ref,class Ptr>
class ListIterator
{
public:
typedef ListNode<T>* PNode;
typedef ListIterator<T, Ref, Ptr>Self;
PNode _node;
ListIterator(PNode node)
:_node(node)
{}
Ref operator*()
{
return _node->val;
}
Ptr operator->()
{
return &(_node->val);
}
Self& operator++()
{
_node = _node->_pnext;
return *this;
}
Self operator++(int)
{
Self temp(*this);
_node = _node->_pnext;
return temp;
}
Self operator--()
{
_node = _node->_prev;
return *this;
}
Self operator--(int)
{
Self temp(*this);
_node = _node->_prev;
return temp;
}
bool operator!=(const Self& x)
{
return _node != x._node;
}
bool operator==(const Self& x)
{
return _node == x._node;
}
};
template<class T>
class List
{
public:
typedef ListNode<T> Node;
typedef Node* PNode;
typedef ListIterator<T, T&, T*> iterator;
List()
{
_head = new Node;
_head->_pnext = _head;
_head->_prev = _head;
}
List(int n, const T& val = T())
{
_head = new Node;
_head->_pnext = _head;
_head->_prev = _head;
for (int i = 0; i < n; ++i)
{
PushBack(val);
}
}
template<class Iterator>
List(Iterator first, Iterator last)
{
_head = new Node;
_head->_pnext = _head;
_head->_prev = _head;
while (first != last)
{
PushBack(*first);
first++;
}
}
List(const List<T>& x)
{
_head = new Node;
_head->_pnext = _head;
_head->_prev = _head;
List<T> temp(x.begin(), x.end());
swap(_head, temp);
}
List<T>& operator=(List<T> x)
{
swap(_head, x._head);
return *this;
}
~List()
{
if (_head)
{
PNode pcur = _head->_pnext;
while (pcur != _head)
{
PNode next = pcur->_pnext;
delete pcur;
pcur = next;
}
delete _head;
_head = nullptr;
}
}
iterator begin()
{
return iterator(_head->_pnext);
}
iterator end()
{
return iterator(_head);
}
T& Front()
{
return _head->_pnext->val;
}
const T& Front()const
{
return _head->_pnext->val;
}
T& Back()
{
return _head->_prev->val;
}
void PushBack(const T& val)
{
PNode NewNode = new Node(val);
PNode prev = _head->_prev;
prev->_pnext = NewNode;
NewNode->_prev = prev;
NewNode->_pnext = _head;
_head->_prev = NewNode;
}
void PopBack()
{
PNode del = _head->_prev;
if (del != _head)
{
_head->_prev = del->_prev;
del->_prev->_pnext = _head;
delete del;
}
}
void PushFront(const T& val)
{
PNode NewNode = new Node(val);
NewNode->_prev = _head;
NewNode->_pnext = _head->_pnext;
_head->_pnext->_prev = NewNode;
_head->_pnext = NewNode;
}
void PopFront()
{
PNode cur = _head->_pnext;
if (cur != _head)
{
_head->_pnext = cur->_pnext;
cur->_pnext->_prev = _head;
delete cur;
}
}
//在pos位置前插入val
iterator Insert(iterator pos, const T& val)
{
PNode NewNode = new Node(val);
PNode pCur = pos._node;
NewNode->_pnext = pCur;
NewNode->_prev = pCur->_prev;
NewNode->_prev->_pnext = NewNode;
pCur->_prev = NewNode;
}
iterator Erase(iterator pos)
{
PNode pCur = pos._node;
PNode prev = pCur->_prev;
PNode next = pCur->_pnext;
if (pCur != _head)
{
prev->_pnext = next;
next->_prev = pre;
delete pCur;
pCur = nullptr;
pos = iterator(next);
}
return next;
}
void Clear()
{
PNode cur = _head->_pnext;
while (cur != _head)
{
PNode temp = cur->_pnext;
delete cur;
cur = temp;
}
_head->_pnext = _head;
_head->_prev = _head;
}
size_t Size()
{
size_t size;
PNode cur = _head->_pnext;
while (cur != _head)
{
size++;
cur = cur->_pnext;
}
return size;
}
bool Empty()const
{
return _head->_pnext == _head;
}
void Resize(size_t size, const T& val = T())
{
size_t Oldsize = Size();
if (Oldsize <= size)
{
for (size_t i = Oldsize; i < size; ++i)
PushBack(val);
}
else
{
for (size_t i = size; i > Oldsize; --i)
PopBack();
}
}
private:
PNode _head;
};
}
template<class T>
void PrintList(Bai::List<T>& x)
{
auto it = x.begin();
while (it != x.end())
{
cout << *it << " ";
it++;
}
}
int main()
{
int array[] = { 1,2,3,4,5,6,7,8,9 };
Bai::List<int> L(array, array + sizeof(array) / sizeof(array[0]));
PrintList(L);
system("pause");
return 0;
}