STL中的 list是一个有头节点的双向循环链表,掌握了lst的list,vector自然不在话下。
STL中使用迭代器(iterator)指向list的节点,并进行增删查改等操作。下面我们模拟实现STL中list的常用操作。
首先,我们要知道,list本身和list的节点是不同的结构,需要分开设计,以下是模拟STL list的节点结构:
template<class T>
struct MyListNode
{
MyListNode<T>* _prev;
MyListNode<T>* _next;
T _data;
MyListNode(const T& x)//节点的构造函数
:_data(x)
, _next(NULL)
, _prev(NULL){}
};
显然,list是一个有头节点的双向循环链表,示意图如下:
在设计list迭代器时,注意删除元素导致的迭代器失效:
template<class T, class Ref, class Ptr>
struct ListIterator//迭代器
{
typedef MyListNode<T> Node;
Node* _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--()
{
_node = _node->_prev;
return *this;
}
Self operator++(int)//前置++
{
Self tmp(*this);
_node = _node->_next;
return tmp;
}
Self operator--(int)
{
Self tmp(*this);
_node = _node->_prev;
return _tmp;
}
bool operator != (const Self& s)const
{
return _node != s._node;
}
};
下面是list数据结构的模拟实现代码:
template<class T>
class List
{
public:
typedef MyListNode<T> Node;
typedef ListIterator<T, T&, T*> Iterator;//const 型迭代器和非const型
typedef ListIterator<T, const T&, const T*> ConstIterator;
List()
{
_head = BuyNode(T());//用匿名对象初始化
_head->_next = _head;
_head->_prev = _head;
}
~List()
{
Clear();
delete _head;
_head = NULL;
}
void Clear()
{
Node* cur = _head->_next;
while (cur != _head)
{
Node* next = cur->_next;//防止迭代器失效
delete cur;
cur = next;
}
}
Iterator Begin()
{
return _head->_next;
}
Iterator End()
{
return Iterator(_head);
}
ConstIterator Begin()const
{
return ConstIterator(_head->_next);
}
ConstIterator End()const
{
return ConstIterator(_head);
}
void PushBack(const T& x)
{
Node* tail = _head->_prev;
Node* tmp = BuyNode(x);
tail->_next = tmp;
tmp->_prev = tail;
_head->_prev = tmp;
tmp->_next = _head;
}
void PopBack()//尾删
{
Iterator tmp = End();
Erase(--tmp);
}
void PushFront(const T& x)//头插
{
Insert(Begin(), x);
}
void PopFront()//头删,不能删除头结点
{
Erase(Begin());
}
Iterator Insert(Iterator pos, const T& x)//任意位置插入
{
Node* tmp = BuyNode(x);
Node* next = pos._node->_next;
Node* prev = pos._node->_prev;
prev->_next = tmp;
tmp->_prev = prev;
tmp->_next = next;
next->_prev = tmp;
return tmp;
}
Iterator Erase(Iterator pos)//任意位置删除
{
Node* next = pos._node->_next;
Node* prev = pos._node->_prev;
prev->_next = next;
next->_prev = prev;
delete pos._node;
return next;
}
//翻转
void Reverse()
{
Node* cur = _head;
Node* last = cur->_next;
Node* tmp = cur;
Node* NewHead = NULL;
while (cur)
{
tmp = cur;
cur = cur->_next;
tmp->_next = NewHead;
tmp->_prev = cur;
NewHead = tmp;
}
_head = NewHead;
_head->_prev = last;
last->_next = _head;
}
//将一段区间移动到pos之前
Iterator Transfor(Iterator pos, Iterator first, Iterator last)
{
Node* cur = pos._node;
Node* prev = cur->_prev;
Node* firstN = first._node;
Node* lastN = last._node;
Node* next = lastN->_next;
prev->_next = firstN;
firstN->_prev = prev;
lastN->_next = cur;
cur->_prev = lastN;
cur->_next = next;
next->_prev = cur;
return next;
}
//去重(只能去除连续相同的)
void Unique()
{
Iterator first = Begin();
Iterator last = End();
if (first == last)
return;
Iterator next = first;
while (next != last)
{
if (*first == *next)
{
next = Erase(next);//防止迭代器失效
}
else
{
first = next;
next = first;
++next;
}
}
}
//删除所有值为data的元素
void Remove(const T& data)
{
Iterator first = Begin();
Iterator last = End();
Iterator next = first;
while (first != last)
{
++next;
if (*first == data)
{
Erase(first);
}
first = next;
}
}
//查找
Iterator Find(List<int>& l1, const T& data)
{
List<int>::Iterator it1 = l1.Begin();
while (it1 != l1.End())
{
if (it1._node->_data == data)
{
return it1;
}
else
{
++it1;
}
}
return NULL;
}
protected:
Node* BuyNode(const T& x)
{
return new Node(x);
}
private:
Node* _head;
};
void PrintMylst(const List<int>& l1)
{
List<int>::ConstIterator it1 = l1.Begin();
while (it1 != l1.End())
{
cout << *it1 << " ";
++it1;
}
cout << endl;
}
测试用例:
void Test()
{
List<int> l1;
l1.PushBack(1);
l1.PushBack(2);
l1.PushBack(3);
l1.PushBack(4);
l1.PushFront(5);
/*l1.PopFront();
l1.PopFront();*/
PrintMylst(l1);
}
int main()
{
Test();
system("pause\n");
return 0;
}
结果如下: