list是標準模板庫中的一個容器,實際上是一條帶頭節點的雙向鏈表。通過與迭代器的組合使用,使得工作效率大大提高。
要注意:迭代器只是爲了訪問、修改和遍歷對象,不對空間進行管理。
#pragma once
#include <iostream>
using namespace std;
//定義鏈表結點結構體
template<class T>
struct __ListNode
{
T _data;
__ListNode<T>* _next;
__ListNode<T>* _prev;
__ListNode(const T& d)
:_data(d)
, _next(NULL)
, _prev(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)
{}
__ListIterator()
{}
Ref operator*() //解引用的重載
{
return _node->_data;
}
Self& operator++() //前置++,像指針一樣可以移動一位
{
_node = _node->_next;
return *this;
}
Ptr operator->() //重載->
{
return &(*_node)._data;
}
Self operator++(int) //後置++
{
Node* cur = _node;
_node = _node->_next;
return cur;
}
Self& operator--()
{
_node = _node->_prev;
return *this;
}
Self operator--(int)
{
Node* cur = _node;
_node = _node->_prev;
return cur;
//return Self(cur);//先構造在拷貝,編譯器優化,效率高
}
bool operator==(const Self& s) const
{
return this->_node == s._node;
}
bool operator!=(const Self& s) const
{
return this->_node != s._node;
}
Node* _node;
};
//模擬實現list
template<class T>
class List
{
typedef __ListNode<T> Node;
public:
typedef __ListIterator<T, T&, T*> Iterator;
typedef __ListIterator<T, const T&, const T*> ConstIterator;
Node* GetNode(const T& d) //申請結點
{
return new Node(d);
}
List() //雙向循環列表
{
_head = GetNode(T());//匿名對象
_head->_next = _head;
_head->_prev = _head;
}
~List()
{
if (_head->_next == _head)
{
delete _head;
_head = NULL;
}
}
void PushBack(const T& d) //後插,學會代碼複用
{
/*Node* tail = _head->_prev;
Node* tmp = GetNode(d);
tail->_next = tmp;
tmp->_prev = tail;
tmp->_next = _head;
_head->_prev = tmp;*/
Insert(End(), d);
}
void PopBack() //後刪
{
if (_head->_next == _head)
{
return;
}
Erase(--End());
/*Node* del = _head->_prev;
Node* prev = del->_prev;
_head->_prev = prev;
prev->_next = _head;
delete del;*/
}
void PushFront(const T& d) //前插
{
Insert(Begin(), d);
}
void PopFront() //前刪
{
if (_head->_next == _head)
{
return;
}
else
{
Erase(Begin());
}
}
//在pos前面進行插入
void Insert(Iterator pos, const T& d)
{
assert(pos._node);
Node* newnode = GetNode(d);
Node* prev = pos._node->_prev;
Node* cur = pos._node;
prev->_next = newnode;
newnode->_next = cur;
newnode->_prev = prev;
cur->_prev = newnode;
}
//刪除指定位置的結點
Iterator Erase(Iterator& pos) //注意迭代器失效的問題
{
assert(pos._node&&pos._node != _head);
Node* prev = pos._node->_prev;
Node* next = pos._node->_next;
prev->_next = next;
next->_prev = prev;
delete pos._node;
return next;
}
template <typename InputIterator>
void Insert(Iterator pos, InputIterator first, InputIterator last) //指定位置插入一段區間
{
while (first != last)
{
Insert(pos, *first);
++first;
}
}
bool Empty() const //判空
{
return _head == _head->_next;
}
Iterator Begin()
{
return Iterator(_head->_next);
}
ConstIterator Begin() const
{
return ConstIterator(_head->_next);
}
Iterator End()
{
return Iterator(_head);
}
ConstIterator End() const
{
return ConstIterator(_head);
}
private:
Node* _head; //指向頭結點的指針
};
void PrintList(const List<int>& l)
{
List<int>::ConstIterator it = l.Begin();
while (it != l.End())
{
cout << *it << " ";
++it;
}
cout << endl;
}
測試:
void TestList()
{
List<int> l1;
l1.PushBack(1);
l1.PushBack(2);
l1.PushBack(3);
l1.PushBack(4);
PrintList(l1);
l1.PopBack();
l1.PopBack();
l1.PopBack();
l1.PopBack();
l1.PopBack();
PrintList(l1);
}
void TestList1()
{
List<int> l1; //4 3 2 1
l1.PushFront(1);
l1.PushFront(2);
l1.PushFront(3);
l1.PushFront(4);
PrintList(l1);
List<int>::Iterator it = l1.Begin();
++it;
l1.Insert(it, 10); //4 10 3 2 1
PrintList(l1);
++it;
it = l1.Erase(it); //4 10 3 1
PrintList(l1);
l1.PopFront();
l1.PopFront();
l1.PopFront();
l1.PopFront();
l1.PopFront();
PrintList(l1);
}