list:带头结点的双向循环链表
我们先来看看在STL中list的各个接口的使用
#include<windows.h>
#include<iostream>
#include <algorithm>
#include<list>
using namespace std;
//迭代器的使用
void Testlist()
{
list<int> l1;
l1.push_back(1);
l1.push_back(2);
l1.push_back(3);
l1.push_back(4);
l1.push_back(5);
//正向迭代器
list<int>::iterator it1 = l1.begin();
while (it1 != l1.end())
{
cout << *it1 << " ";
it1++;
}
cout << endl;
//反向迭代器
list<int>::reverse_iterator it2 = l1.rbegin();
while (it2 != l1.rend())
{
cout << *it2 << " ";
it2++;
}
cout << endl;
//insert:在指定位置的数据之前插入
list<int>::iterator it3 = l1.begin();
it3++;
l1.insert(it3, 10);
it3 = l1.begin();
while (it3 != l1.end())
{
cout << *it3 << " ";
it3++;
}
cout << endl;
//erase:删除指定位置的元素(由于list中没有find接口,引入算法头文件)
list<int>::iterator it4 = find(l1.begin(), l1.end(), 10);
if (it4 != l1.end())
l1.erase(it4);
it4 = l1.begin();
while (it4 != l1.end())
{
cout << *it4 << " ";
it4++;
}
cout << endl;
//迭代器失效
list<int>::iterator it5 = l1.begin();
//while (it5 != l1.end())
//{
// if (*it5 % 2 == 0)
// l1.erase(it5);//释放之后it5指向随机空间
//}
//++it5;//对随机空间++,导致程序崩溃 ,若没有删除就会多++一次。
//解决方法1:先加加,再删除
if (*it5 %2==0)
{
it5++;
l1.erase(it5);
}
//解决办法2:利用返回值对其进行改进
it5 = l1.begin();
if (*it5 %2==0)
{
it5 = l1.erase(it5);
}
else
{
it5++;
}
}
int main()
{
Testlist();
system("pause");
return 0;
}
这是我们的运行结果
我们下来参照list来模拟实现
#include<iostream>
#include<assert.h>
using namespace std;
template<class T>
struct __ListNode
{
T _data;
__ListNode<T> *_prev;
__ListNode<T> *_next;
__ListNode(const T&x)
:_data(x)
, _prev(NULL)
, _next(NULL)
{}
};
//T,T&,T*
template<class T, class Ref, class Ptr>
struct __ListIterator
{
typedef __ListNode<T> Node;
typedef __ListIterator<T, Ref, Ptr> Self;
__ListIterator(Node *x)
:_node(x)
{}
// T& 出了作用域,对象还存在所以用Ref
Ref operator*()
{
return _node->_data;
}
//T* ->返回数据地址
Ptr operator->()
{
return &_node->_data;
}
//前置++
Self & operator++()
{
_node = _node->_next;
return *this;
}
//后置++
Self operator++(int)
{
Node* tmp = _node; //先保存_node的值
_node = _node->_next;//让_node指向它的下一个
return tmp;
}
//前置--
Self &operator--()
{
_node = _node->_prev;
return *this;
}
//后置--
Self operator--(int)
{
Node* tmp = _node;//先保存_node的值
_node = _node->_prev;//让_node指向它的上一个
return tmp;
}
//判断!=
bool operator != (const Self& s) const
{
return _node != s._node;
}
//判断==
bool operator==(const Self &s) const
{
return _node == s._node;
}
Node *_node;
};
template<class T>
class List
{
public:
typedef __ListNode<T> Node;
typedef __ListIterator<T, T&, T*> Iterator;
//List构造函数
List()
{
_head = new Node(T());
_head->_prev = _head;
_head->_next = _head;
}
//析构函数
~List()
{
Clear();
delete _head;//释放_head
_head = NULL;//将_head置为空
}
//返回类型为迭代器
Iterator Begin()
{
//return Iterator(_head->_next);
return _head->_next;//发生隐式类型转换
//构造函数和拷贝构造同一步骤使用,编译器会进行自动优化
}
Iterator End()
{
//return Iterator(_head);//发生隐式类型转换
return _head;
}
//在pos前插入x
void Insert(Iterator pos, const T &x)
{
Node *next = pos._node;
Node *prev = next->_prev;
Node *cur = new Node(x);
cur->_prev = prev;
prev->_next = cur;
cur->_next = next;
next->_prev = cur;
}
//删除指定位置
Iterator Erase(Iterator pos)
{
assert(pos!=End()&&pos._node);
Node* cur = pos._node;
Node* prev = cur->_prev;
Node* next = cur->_next;
prev->_next = next;
next->_prev = prev;
delete cur;
pos = prev;//实现即删即写(erase之后++,不用else)
return pos;//防止迭代器失效
}
//判断是否为空
bool Emply()
{
return _head == _head->_next;
}
//查找
Iterator Find(const T&x)
{
Iterator it = Begin();
while (it != End())
{
if (*it == x)
return it;
it++;
}
return it;
}
//尾插
void PushBack(const T&x)
{
return Insert(End(), x);
}
//尾删
//因为复用了Erase(),所以PopBack的返回值也为Iterator
Iterator PopBack()
{
return Erase(--End());
}
//头插
void PushFront(const T&x)
{
return Insert(Begin(), x);
}
//头删
//因为复用了Erase(),所以PopFront的返回值也为Iterator
Iterator PopFront()
{
return Erase(Begin());
}
//清空
void Clear()
{
Iterator it = Begin();
while (it != End())
{
Node*del = it._node;
++it;
delete del;
}
}
//打印
void Print()
{
Iterator it = Begin();
while (it != End())
{
cout << *it << " ";
cout << endl;
++it;
}
}
protected:
Node *_head;
};