一、什么是List?
List是STL标准库中的一个容器,相当于双向循环的链表,而且此链表有头结点
二、List的优点?
1.通用性好(因为List的实现使用了模板)
2.效率高
3.任意位置的插入和删除操作的时间复杂度为O(1)
三、什么是迭代器?
迭代器本质上是指针
那为什么不直接操作指针,而是把指针封装成迭代器呢?
(1)vector的迭代器可以是原生态的指针
(2)list的迭代器如果使用原生态的指针,那指针++就得不到当前结点的下一个结点,故原生态的指针满足不了list这样的结构,在一个原因是为了实现通用的算法
四、如何给一个容器加迭代器?
使用方法Begin()和End(),这两个方法可以把容器和迭代器联系起来
五、List的实现
1.头插
void PushFront(const T&data)
{
pNode NewNde = new Node(data);
_pHead->_pNext->_pPre = NewNode;
NewNde->_pPre = _pHead;
NewNde->_pNext = _pHead->_pNext;
_pHead->_pNext = NewNde;
}
2.头删
void PopFront()
{
//空链表
if (Empty())
return;
//链表非空
pNode pDel = _pHead->_pNext;
_pHead->_pNext = pDel->_pNext;
pDel->_pNext->_pPre = _pHead;
delete pDel;
}
3.尾插
//不用判断空链表,因为链表中有结点的情况包含了空链表的情况
void PushBack(const T&data)
{
pNode pTail = _pHead->_pPre;
pNode NewNode = new Node(data);
pTail->_pNext = NewNode;
NewNode->_pPre = pTail;
NewNode->_pNext = _pHead;
_pHead->_pPre = NewNode;
}
4.尾删
void PopBack()
{
//空链表
if (Empty())
return;
//链表非空
pNode pPreTail = _pHead->_pPre->_pPre;
delete pPreTail->_pNext;
pPreTail->_pNext = _pHead;
_pHead->_pPre = pPreTail;
}
5.任意位置的插入
//不用判断空链表的情况
//双向链表一般是吧data插入pos的前面,单链表是吧data插入到pos的后面
pNode Insert(pNode pos, const T&data)
{
pNode NewNode = new Node(data);
pos->_pPre->_pNext = NewNode;
NewNode->_pNext = pos;
NewNode->_pPre = pos->_pPre;
NewNode->_pNext = pos;
return NewNode;
}
6.任意位置的删除
pNode Erase(pNode pos)
{
pNode pRet = pos->_pNext;
//空链表
if (Empty())
return NULL;
//非空链表
pos->_pPre->_pNext = pos->_pNext;
pos->_pNext->_pPre = pos->_pPre;
delete pos;
return pRet;
}
7.清空链表中所有的结点
void Clear()
{
pNode pDel = _pHead->_pNext;
while (!Empty())
{
pDel = _pHead->_pNext;
_pHead->_pNext = pDel->_pNext;
delete pDel;
}
_pHead->_pPre = _pHead;
}
七、源代码
#include<iostream>
using namespace std;
template<class T>
struct ListNode
{
ListNode(const T&data = T())
:_pNext(NULL)
, _pPre(NULL)
, _data(data)
{}
ListNode<T>*_pNext;
ListNode<T>*_pPre;
T _data;
};
////模拟实现迭代器
template<class T>
class ListIterator
{
typedef ListNode<T>* pNode;
typedef ListIterator<T> Self;
public:
//构造函数
ListIterator()
:_pCur(NULL)
{}
ListIterator(pNode pCur)
:_pCur(pCur)
{}
//拷贝构造函数
ListIterator(const Self& s)
:_pCur(s._pCur)
{}
//重载前置++
Self& operator++()
{
_pCur = _pCur->_pNext;
return*this;
}
//重载后置++
Self operator++(int)
{
Self temp(*this);
_pCur = _pCur->_pNext;
return temp;
}
//重载前置--
Self& operator--()
{
_pCur = _pCur->_pPre;
return _pCur;
}
//重载后置--
Self operator--(int)
{
Self temp(*this);
_pCur = _pCur->_pPre;
return temp;
}
//重载不等于和等于
bool operator!=(const Self& s)
{
return _pCur != s._pCur;
}
bool operator==(const Self& s)
{
return _pCur == s._pCur;
}
//重载对指针的解引用
T& operator*()
{
return _pCur->_data;
}
//重载箭头访问符
T* operator->()
{
return &(_pCur->_data);
}
private:
pNode _pCur;
};
//模拟实现List
template<class T>
class List
{
public:
typedef ListNode<T> Node;
typedef ListNode<T>* pNode;
public:
typedef ListIterator<T> Iterator;
public:
//构造函数
List()
{
//构建链表头结点
CreateListHead();
}
List(T*array,size_t size)
{
CreateListHead();
for (size_t i = 0; i < size; ++i)
PushBack(array[i]);
}
//拷贝构造函数
List(const List<T>&l);
//赋值运算符重载
List<T>& operator=(const List<T>& l);
//析构函数
~List()
{
Clear();
delete _pHead;
_pHead = NULL;
}
//////////////////////////////////////////////////////////////////////////////////////////////
////迭代器的接口
Iterator Begin()
{
return Iterator(_pHead->_pNext);
}
Iterator End()
{
return Iterator(_pHead);
}
/////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////
//以下是List的一些操作
/////////////////////////////////////////////////////////////////////////////////////////////
//尾插
//不用判断空链表,因为链表中有结点的情况包含了空链表的情况
void PushBack(const T&data)
{
pNode pTail = _pHead->_pPre;
pNode NewNode = new Node(data);
pTail->_pNext = NewNode;
NewNode->_pPre = pTail;
NewNode->_pNext = _pHead;
_pHead->_pPre = NewNode;
}
//尾删
void PopBack()
{
//空链表
if (Empty())
return;
//链表非空
pNode pPreTail = _pHead->_pPre->_pPre;
delete pPreTail->_pNext;
pPreTail->_pNext = _pHead;
_pHead->_pPre = pPreTail;
}
//头插
//不用判断空链表的情况
void PushFront(const T&data)
{
pNode NewNde = new Node(data);
_pHead->_pNext->_pPre = NewNode;
NewNde->_pPre = _pHead;
NewNde->_pNext = _pHead->_pNext;
_pHead->_pNext = NewNde;
}
//头删
void PopFront()
{
//空链表
if (Empty())
return;
//链表非空
pNode pDel = _pHead->_pNext;
_pHead->_pNext = pDel->_pNext;
pDel->_pNext->_pPre = _pHead;
delete pDel;
}
//任意位置的插入
//不用判断空链表的情况
//双向链表一般是吧data插入pos的前面,单链表是吧data插入到pos的后面
pNode Insert(pNode pos, const T&data)
{
pNode NewNode = new Node(data);
pos->_pPre->_pNext = NewNode;
NewNode->_pNext = pos;
NewNode->_pPre = pos->_pPre;
NewNode->_pNext = pos;
return NewNode;
}
//任意位置的删除
pNode Erase(pNode pos)
{
pNode pRet = pos->_pNext;
//空链表
if (Empty())
return NULL;
//非空链表
pos->_pPre->_pNext = pos->_pNext;
pos->_pNext->_pPre = pos->_pPre;
delete pos;
return pRet;
}
//判断链表是否为空链表
bool Empty()const
{
return _pHead->_pNext == _pHead;
}
//获取链表的结点数
size_t Size()
{
size_t count = 0;
pNode pCur= _pHead->_pNext;
while (pCur!=_pHead)
{
count++;
pCur = pCur->_pNext;
}
}
//将链表中的所有结点置空
void Clear()
{
pNode pDel = _pHead->_pNext;
while (!Empty())
{
pDel = _pHead->_pNext;
_pHead->_pNext = pDel->_pNext;
delete pDel;
}
_pHead->_pPre = _pHead;
}
//重载输出运算符
friend ostream& operator << (ostream& _cout, const List<int>& l)
{
for (size_t i = 0; i < l.Size(); ++i)
_cout << l[i] << " ";
return _cout;
}
private:
//创建链表头结点
void CreateListHead()
{
_pHead = new Node;
_pHead->_pNext = _pHead;
_pHead->_pPre = _pHead;
}
private:
pNode _pHead;
};
void Print(List<int>& l)//打印链表
{
List<int>::Iterator it = l.Begin();
while (it != l.End())
{
cout << *it << "---->";
++it;//用前置++,不会创建临时对象,比后置++的效率高
}
cout << "NULL" << endl;
}
//找数据data在链表中的的位置
template<class Iterator,class T>
Iterator Find(Iterator start, Iterator finish, const T&data)
{
while (start != finish)
{
if (*start == data)
return start;
++start;
}
return finish;
}
void TestList()
{
List<int> L;
L.PushBack(1);
L.PushBack(2);
L.PushBack(3);
L.PushBack(4);
L.PushBack(5);
Print(L);
L.PopFront();
L.PopFront();
Print(L);
}
int main()
{
TestList();
system("pause");
return 0;
}