STL------List與迭代器的實現
阿新 • • 發佈:2018-12-26
1. List
List是STL庫(標準模板庫)中的一個容器。它的實質上就是一個雙向帶頭迴圈連結串列,這樣的設計有以下幾個優點:
- 隨機插入資料時,不用遍歷連結串列,去找某一特定位置
- 尾插時,只需head->prev就可找到,提高了效率
- 在連結串列中刪除資料時,也只需給出迭代器的位置即可,不需遍歷連結串列找
到其前一個,或者採用替換刪除的方法刪除節點
2. 迭代器
迭代器是一種行為類似指標的物件,它提供類似指標的功能,對容器的內容進行走訪,而指標的各種行為中最常見也最重要的便是“內容提領”和“成員訪問”。因此,迭代器最重要的程式設計工作就是對operator*和operator->進行過載工作。
3. List的迭代器
List 的迭代器中過載operator++ 和 operator– ,可以使迭代器向指標一樣,按順序訪問連結串列的元素
4. 模擬實現
//連結串列的結點
template<class T>
struct ListNode
{
ListNode<T>* _next;
ListNode<T>* _prev;
T _data;
ListNode(const T& x = T())
:_data(x)
, _next(nullptr)
, _prev(nullptr )
{}
};
//模板引數,定義為型別T,T的引用,T的指標
template<class T, class Ref, class Ptr>
struct MyIterator
{
typedef ListNode<T> Node;//將node節點重名名為node
typedef MyIterator<T, Ref, Ptr> Self;//將自己重新命名為self
Node* _node;
MyIterator(Node* node)
:_node(node)
{}
Ref operator *()//引用
{
return _node->_data;
}
Ptr operator->()//指標
{
return &(operator*());
}
Self& operator++()//前置++
{
_node = _node->_next;
return *this;
}
Self operator++(int)//後置++
{
Self tmp(_node);
_node = _node->_next;
return tmp;
}
Self& operator--()//前置--
{
_node = _node->_prev;
return *this;
}
Self operator--(int)//後置--
{
Self tmp(_node);
_node = _node->_prev;
return tmp;
}
bool operator==(const Self& s) const//const迭代器
{
return _node == s._node;
}
bool operator!=(const Self& s) const
{
return _node != s._node;
}
};
template<class T>
class MyList
{
typedef ListNode<T> Node;
public:
typedef MyIterator<T, T&, T*> Iterator;//宣告
typedef MyIterator<T, const T&, const T*> ConstIterator;
MyList()
{
_head = new Node;
_head->_next = _head;
_head->_prev = _head;
}
void Insert(Iterator pos, const T& x)
{
Node* cur = pos._node;
Node* next = cur->_next;
Node* newnode = new Node(x);
//cur next newnode
newnode->_next = next;
next->_prev = newnode;
newnode->_prev = cur;
cur->_next = newnode;
}
void Erase(Iterator pos)
{
Node* cur = pos._node;
Node* next = cur->_next;
Node* prev = cur->_prev;
//prev pos next
prev->_next = next;
next->_prev = prev;
delete cur;
}
void PushBack(const T& x)
{
Node* tail = _head->_prev;
Node* newnode = new Node(x);
newnode->_next = tail->_next;
_head->_prev = newnode;
tail->_next = newnode;
newnode->_prev = tail;
}
Iterator Begin()//迭代器的開始
{
return _head->_next;
}
Iterator End()//迭代器的結束
{
return _head;
}
ConstIterator Begin() const
{
//return Iterator(_head->_next);
return _head->_next;
}
ConstIterator End() const
{
//return Iterator(_head);
return _head;
}
protected:
Node* _head;
};
測試程式碼:
void PrintList( MyList<int>& l)
{
MyList<int>::Iterator it = l.Begin();
while (it != l.End())
{
cout << *it << " ";
++it;
}
cout << endl;
}
void Test()
{
MyList<int> l;
l.PushBack(1);
l.PushBack(2);
l.PushBack(3);
l.PushBack(4);
l.PushBack(5);
PrintList(l);
MyList<int>::Iterator it = l.Begin();
while (it != l.End())
{
if ((*it._node)._data == 3)
{
l.Insert(it, 0);
break;
}
++it;
}
PrintList(l);
while (it != l.End())
{
if ((*it._node)._data == 0)
{
l.Erase(it);
break;
}
++it;
}
PrintList(l);
}