1. 程式人生 > >C++模擬實現容器list(含迭代器)

C++模擬實現容器list(含迭代器)

list同之前實現過的容器vector類似,都是STL眾多容器中的一個。STL中實現的連結串列是帶頭結點的雙向迴圈連結串列,這種連結串列相比於之前我們在C語言和C++初級階段模板實現的連結串列或者雙向連結串列更加的方便,更加方便的遍歷,方便查詢,方便各種操作。
在vector中,我們是用一個原生態的指標來當做迭代器,但是在list中我們只能對指標進行封裝來實現迭代器。
這裡寫圖片描述
list的基本結構就如上圖所示,接下來看看具體實現程式碼

#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include <stdlib.h>
#include <iostream>
using namespace std; template<class T> struct ListNode { ListNode(const T& data = T()) : _pPre(0) , _pNext(0) , _data(data) {} ListNode<T>* _pPre; ListNode<T>* _pNext; T _data; }; //迭代器 template<class T,class Ref,class Ptr> class ListIterator { typedef
ListIterator<T, Ref, Ptr> Self; public: ListIterator() :_pCur(0) {} ListIterator(ListNode<T>* pCur) : _pCur(pCur) {} ListIterator(const Self& s) : _pCur(s._pCur) {} Ref operator*() { return _pCur->_data; } Ptr operator
->() { return &(operator*()); //return &(_pCur->_data); } Self& operator++() { _pCur = _pCur->_pNext; return*this; } Self operator++(int) { Self temp(*this); _pCur = _pCur->_pNext; return temp; } Self& operator--() { _pCur = _pCur->_pPre; return*this; } 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; } ListNode<T>* _pCur; }; template <class T> class List { public: typedef ListIterator<T, T&, T*> Iterator; typedef ListNode<T> Node; public: List()//無參建構函式 : _pHead(new Node) { _pHead->_pNext = _pHead;//帶頭節點的迴圈連結串列 _pHead->_pPre = _pHead; } List(const T* array, size_t size)//有參建構函式 :_pHead(new Node) { _pHead->_pNext = _pHead; _pHead->_pPre = _pHead; for (size_t i = 0; i < size; i++) { PushBack(array[i]); } } List(const List<T>& l)//拷貝建構函式 :_pHead(new Node) { _pHead->_pNext = _pHead; _pHead->_pPre = _pHead; Node* cur = l._pHead->_pNext; for (size_t i = 0; i < l.Size();i++) { PushBack(cur->_data); cur = cur->_pNext; } } List<T>& operator=(const List<T>& l)//賦值運算子過載 { if (this != &l) { Node* pRet = l._pHead->_pNext; for (size_t i = 0; i < l.Size(); i++) { PushBack(pRet->_data); pRet = pRet->_pNext; } } return *this; } ~List()//解構函式 { Clear(); delete _pHead; _pHead = NULL; } Iterator Begin() { return Iterator(_pHead->_pNext); } Iterator End() { return Iterator(_pHead); } void PushBack(const T& data)//尾插 { Node* _pNewNode = new Node(data); if (Empty())//連結串列為空 { _pHead->_pNext = _pNewNode; _pHead->_pPre = _pNewNode; _pNewNode->_pNext = _pHead; _pNewNode->_pPre = _pHead; } else { Node* pTail = _pHead->_pPre; pTail->_pNext = _pNewNode; _pNewNode->_pNext = _pHead; _pNewNode->_pPre = pTail; _pHead->_pPre = _pNewNode; } } void PopBack()//尾刪 { if (Empty())//連結串列為空 { return; } else { Node* del = _pHead->_pPre;//要刪除的節點 Node* tail = del->_pPre;//新的尾節點 delete del; tail->_pNext = _pHead; _pHead->_pPre = tail; } } void PushFront(const T& data)//頭插 { Node* _pNewNode = new Node(data); _pHead->_pNext->_pPre = _pNewNode; _pNewNode->_pNext = _pHead->_pNext; _pNewNode->_pPre = _pHead; _pHead->_pNext = _pNewNode; } void PopFront()//頭刪 { if (Empty()) { return; } else { Node* pDel = _pHead->_pNext; _pHead->_pNext = pDel->_pNext; pDel->_pNext->_pPre = _pHead; delete pDel; } } Iterator Insert(Iterator pos, const T& data)//任意位置插入 { Node* _pNewNode = new Node(data); pos._pCur->_pPre->_pNext = _pNewNode; _pNewNode->_pNext = pos._pCur; _pNewNode->_pPre = pos._pCur->_pPre; pos._pCur->_pPre = _pNewNode; return Iterator(_pNewNode); } Iterator Erase(Iterator pos)//任意位置刪除 { Node* pCur = pos._pCur->_pNext; pos._pCur->_pNext->_pPre = pos._pCur->_pPre; pos._pCur->_pPre->_pNext = pos._pCur->_pNext; delete pos._pCur; return Iterator(pCur); } Iterator Find(const T& d)//通過迭代器來查詢 { Iterator it = Begin(); while (it != End()) { if ((*it) == d) return it; it++; } return End(); } bool Empty()const//判斷連結串列是否為空 { return _pHead->_pNext == _pHead; } size_t Size()const//返回連結串列元素個數 { Node* pCur = _pHead->_pNext; size_t count = 0; while (pCur != _pHead) { ++count; pCur = pCur->_pNext; } return count; } T& Front()//返回第一個節點 { return _pHead->_pNext->_data; } const T& Front()const { return _pHead->_pNext->_data; } T& Back()//返回尾節點 { return _pHead->_pPre->_data; } const T& Back()const { return _pHead->_pPre->_data; } void Clear()//清空連結串列 { Iterator it = Begin(); while (it != End()) { it = Erase(it); } _pHead->_pNext = _pHead; _pHead->_pPre = _pHead; } private: ListNode<T>* _pHead; }; void PrintList( List<int>& l)//列印連結串列 { List<int>::Iterator It = l.Begin(); while (It != l.End()) { cout << *It << " "; ++It; } cout << endl; }

測試程式碼:

void FunTest1()
{
    //無參建構函式
    List<int> l1;

    //有參建構函式
    int arr[5] = { 1, 2, 3, 4, 5 };
    List<int> l2(arr, 5);
    PrintList(l2);

    //拷貝建構函式
    List<int> l3(l2);

    //賦值運算子過載
    l1 = l2;
}
void FunTest2()
{
    List<int> l1;
    l1.PushBack(1);
    l1.PushBack(2);
    l1.PushBack(3);
    l1.PushBack(4);
    l1.PushBack(5);
    l1.PushBack(6);
    l1.PushFront(7);
    PrintList(l1);
    cout << l1.Size() << endl;

    l1.PopBack();
    l1.PopBack();
    l1.PopBack();
    l1.PopFront();
    l1.PopFront();
    PrintList(l1);
    cout << l1.Size() << endl;
}
void FunTest3()
{
    List<int> l1;
    l1.PushBack(1);
    l1.PushBack(2);
    l1.PushBack(3);
    l1.PushBack(4);
    l1.PushBack(5);
    List<int>::Iterator pos = l1.Find(3);
    l1.Insert(pos, 0);
    PrintList(l1);

    l1.Erase(pos);
    PrintList(l1);

}

執行結果:
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述