【C++】模板類連結串列
阿新 • • 發佈:2019-02-09
上一篇部落格介紹了模板類順序表,此篇部落格主要是模板類連結串列的實現。
當然,模板也有利弊,雖然它複用了程式碼,節省資源,可以更快的迭代開發,增強了程式碼的靈活性。但是模板讓程式碼變得錯綜複雜,不易維護,編譯程式碼時間變長。而且,當出現錯誤時,錯誤資訊非常凌亂,親自感受一下就能知道,每次發生一個錯誤,真的要好久才能找到錯在哪裡,不易定位錯誤。#pragma once #include<iostream> #include<string> using namespace std; template<typename T> struct Node { public: Node(const T&x) :_data(x), _next(NULL), _prev(NULL) {} T _data; Node<T>*_next; Node<T>*_prev; }; template<typename T> class LinkList { template<typename T> friend ostream&operator<<(ostream&os, const LinkList<T>&list); public: LinkList() :_head(NULL), _tail(NULL), _sz(0) {} ~LinkList() { Release(); } LinkList(const LinkList<T>&list); //拷貝構造 void PushBack(T x); //尾插 void PopBack(); //尾刪 void PushFront(T x); //頭插 void PopFront(); //頭刪 Node<T>* Find(T x); //查詢指定元素的地址 void Insert(Node<T>* node, T x); //指定位置插入指定資料 void Remove(T x); //刪除指定元素 void RemoveAll(T x); //刪除連結串列裡出現的所有指定資料 void Erase(Node<T>* node); //指定位置刪除 void BubbleSort(); //氣泡排序 int& GetSz() { return _sz; } public: void Release() { Node<T>* cur = _head; while (cur) { Node<T>*tmp = cur; cur = cur->_next; delete tmp; tmp = NULL; } _head = NULL; _tail = NULL; _sz = 0; } Node<T>*_head; Node<T>*_tail; int _sz; }; template<typename T> ostream&operator<<(ostream&os, const LinkList<T>&list) { Node<T>*cur = list._head; while (cur) { os << cur->_data << "-"; cur = cur->_next; } cout << "end" << endl; return os; } template<typename T> LinkList<T>::LinkList(const LinkList<T>&list) { Node<T>* cur = list._head; while (cur) { PushBack(cur->_data); _sz++; cur = cur->_next; } } template<typename T> void LinkList<T>::PushBack(T x) { Node<T>* node = new Node<T>(x); if (NULL == _head) { _head = node; _tail = node; } else { _tail->_next = node; node->_prev = _tail; _tail = node; } _sz++; } template<typename T> void LinkList<T>::PopBack() //尾刪 { if (NULL == _head) { throw string("no data in list"); } else if (NULL == _head->_next) { Release(); } else { _tail = _tail->_prev; delete _tail->_next; _tail->_next = NULL; _sz--; } } template<typename T> void LinkList<T>::PushFront(T x) //頭插 { Node<T>*NewNode = new Node<T>(x); if (NULL == _head) { _head = NewNode; _tail = NewNode; } else { NewNode->_next = _head; _head->_prev = NewNode; _head = NewNode; } _sz++; } template<typename T> void LinkList<T>::PopFront() //頭刪 { if (NULL == _head) { throw string("no data in list"); } else if (NULL == _head->_next) { Release(); } else { _head = _head->_next; delete _head->_prev; _head->_prev = NULL; _sz--; } } template<typename T> Node<T>* LinkList<T>::Find(T x) //查詢指定元素的地址 { Node<T>* cur = _head; while (cur) { if (cur->_data == x) { return cur; } cur = cur->_next; } return NULL; } template<typename T> void LinkList<T>::Insert(Node<T>* node, T x) //指定位置插入指定資料 { Node<T>* cur = _head; Node<T>* NewNode = new Node<T>(x); if (node == _head) { PushFront(x); } else { while (cur) { if (cur == node) { NewNode->_next = cur; NewNode->_prev = cur->_prev; cur->_prev = NewNode; NewNode->_prev->_next = NewNode; _sz++; } cur = cur->_next; } } } template<typename T> void LinkList<T>::Remove(T x) //刪除指定元素 { Node<T>*cur = _head; if (_head->_data == x) { PopFront(); } else { while (cur && (cur->_data != x)) { cur = cur->_next; } if (cur == NULL) { cout << "no such data" << endl; } else { cur->_prev->_next = cur->_next; cur->_next->_prev = cur->_prev; cur->_next = NULL; cur->_prev = NULL; delete cur; _sz--; } } } template<typename T> void LinkList<T>::RemoveAll(T x) //刪除連結串列裡出現的所有指定資料 { Node<T>*cur = _head; while (cur) { if ((cur->_data == x) && (cur->_next != NULL) && (cur->_prev != NULL)) { Node<T> *del = cur; cur = cur->_next; del->_prev->_next = del->_next; del->_next->_prev = del->_prev; del->_next = NULL; del->_prev = NULL; delete del; _sz--; } else if ((cur->_data == x) && (cur->_next == NULL)) { //PopBack(); _tail = cur->_prev; cur->_prev = NULL; _tail->_next = NULL; delete cur; cur = NULL; } else if ((cur->_data == x) && (cur->_prev == NULL)) { //PopFront(); Node<T>*del = cur; cur = cur->_next; _head = _head->_next; _head->_prev = NULL; del->_next = NULL; delete del; del = NULL; } else cur = cur->_next; } } template<typename T> void LinkList<T>::Erase(Node<T>* node) //指定位置刪除 { Node<T>* cur = _head; while (cur) { if ((cur == node) && (cur->_next != NULL) && (cur->_prev != NULL)) { Node<T> *del = cur; cur = cur->_next; del->_prev->_next = del->_next; del->_next->_prev = del->_prev; del->_next = NULL; del->_prev = NULL; delete del; _sz--; } else if ((cur == node) && (cur->_next == NULL)) { _tail = cur->_prev; cur->_prev = NULL; _tail->_next = NULL; delete cur; cur = NULL; } else if ((cur == node) && (cur->_prev == NULL)) { //PopFront(); Node<T>*del = cur; cur = cur->_next; _head = _head->_next; _head->_prev = NULL; del->_next = NULL; delete del; del = NULL; } else cur = cur->_next; } } template<typename T> void LinkList<T>::BubbleSort() //氣泡排序 { Node<T>* cur = _head; Node<T>* EndOk = NULL; while (cur->_next) { Node<T>*incur = _head; while (incur->_next != EndOk) { if (incur->_data > incur->_next->_data) { T tmp = incur->_data; incur->_data = incur->_next->_data; incur->_next->_data = tmp; } incur = incur->_next; } EndOk = incur; cur = cur->_next; } } void test1() { LinkList<int>list; list.PushBack(1); list.PushBack(2); list.PushBack(3); list.PushBack(4); //LinkList<int>list1(list); cout << list << endl; list.PopBack(); cout << list << endl; list.PopBack(); cout << list << endl; list.PopBack(); cout << list << endl; try { list.PopBack(); } catch (string e) { cout << e << endl; } cout << list << endl; try { list.PopBack(); } catch (string e) { cout << e << endl; } cout << list << endl; } void test2() { LinkList<int> list; list.PushFront(1); list.PushFront(2); list.PushFront(3); cout << list << endl; try{ list.PopFront(); } catch (string e) { cout << e << endl; } cout << list << endl; try{ list.PopFront(); } catch (string e) { cout << e << endl; } cout << list << endl; try{ list.PopFront(); } catch (string e) { cout << e << endl; } cout << list << endl; try{ list.PopFront(); } catch (string e) { cout << e << endl; } cout << list << endl; } void test3() { LinkList<int> list; list.PushBack(1); list.PushBack(2); list.PushBack(3); cout << list << endl; Node<int>* ret = list.Find(3); list.Insert(ret, 9); cout << list << endl; LinkList<string> list1; list1.PushBack("ajffas"); list1.PushBack("adgadgagasdjga"); cout << list1 << endl; LinkList<string> list2(list1); cout << list2 << endl; } void test4() { LinkList<int> list; list.PushBack(2); list.PushBack(1); list.PushBack(2); list.PushBack(3); list.PushBack(2); list.PushBack(2); cout << list << endl; /*list.Remove(2); cout << list << endl;*/ list.RemoveAll(2); cout << list << endl; } void test5() { LinkList<int> list; list.PushBack(1); list.PushBack(2); list.PushBack(3); list.PushBack(4); cout << list << endl; /*Node<int>*ret = list.Find(2); list.Erase(ret);*/ cout << list << endl; } void test6() { LinkList<int> list; list.PushFront(1); list.PushFront(2); list.PushFront(3); list.PushFront(4); cout << list << endl; list.BubbleSort(); cout << list << endl; }