1. 程式人生 > >C++實現list類

C++實現list類

#pragma once
#ifndef DSA_LIST_H
#define DSA_LIST_H
#define Posi(T) ListNode<T>*                         //列表位置節點

template<typename T>struct ListNode//列表節點模板類實現
{
    T data;//數值
    Posi(T)pred;//前驅
    Posi(T)succ;//後繼
    ListNode() {}//針對header和railer的構造
    ListNode(T e, Posi(T)p = nullptr, Posi(T)s = nullptr
) :data(e), pred(p), succ(s) {}//構造 Posi(T)inserAsPred(T const&e);//前插入 Posi(T)inserAsSucc(T const&e);//後插入 }; template<typename T>Posi(T) ListNode<T>::inserAsPred(T const& e) { Posi(T)x = new ListNode(e,pred,this);//建立node pred->succ = x; pred = x; return x; } template
<typename T>Posi(T) ListNode<T>::inserAsSucc(T const& e) { Posi(T)x = new ListNode(e, this, succ); succ->pred = x; succ = x; return x; } template<typename T>class List { private:int _size; T* _elem;//規模,資料 Posi(T)header;Posi(T) trailer;//頭尾哨兵 public:int
size() { return _size; }//返回規模 void init();//連結串列初始化 List() { init(); } Posi(T)first() { return header->succ; }//返回首節點 Posi(T)last() { return trailer->pred; }//返回末節點 Posi(T) insertAsFirst(T const& e);//作為首節點插入 Posi(T) insertAslast(T const& e);//作為尾節點插入 Posi(T) insertA(Posi(T)p,T e);//插入在P之後 Posi(T)insertB(Posi(T)p,T e);//插入在P之前 T remove(Posi(T)p);//移除並返回其數值 void sort(Posi(T)p,int n);//排序 Posi(T) find(T const&e, int n , Posi(T)p );//查詢e並返回秩 Posi(T) find(T const&e) { return find(e, _size, trailer); } Posi(T) search(T e,int n,Posi(T)p);//有序連結串列的查詢p的n個真前驅中不大於P的最後者 int List<T>::uniquify();//有序連結串列的去重 void deduplicate();//無序連結串列的去重 void traverse();//連結串列的遍歷 void selectionSort(Posi(T)p, int n);//從P開始之後的n個節點排序 void insertSort(Posi(T)p, int n);//插入排序 void mergeSort(Posi(T)&p, int n);//歸併排序 void merge(Posi(T)&p, int n, List<T>&L, Posi(T)q, int m);//合併 T& operator[](int rank);//過載[]操作符 void copyNodes(Posi(T)p, int n);//複製 Posi(T) selectMax(Posi(T)p, int n);//選位置p之後n個節點中最大的(包括p) ~List() { clear(); delete header; delete trailer; };//解構函式 int clear();//清空列表 }; template<typename T>void List<T>::init() { header = new ListNode<T>;//建立頭指標 trailer = new ListNode<T>;//建立尾指標 header->succ = trailer; header->pred = nullptr;//互聯 trailer->pred = header; trailer->succ = nullptr;//互聯 _size = 0;//記錄規模 } template<typename T>void List<T>::sort(Posi(T)p, int n) { switch (rand() % 3) { case 1:insertSort(p, n); break; case 2:selectionSort(p, n); break; case 3:mergeSort(p, n); break; } } template<typename T>Posi(T) List<T>::insertB(Posi(T)p, T e) { _size++; return p->inserAsPred(e); } template<typename T>Posi(T) List<T>::insertA(Posi(T)p, T e) { _size++; return p->inserAsSucc(e); } template<typename T>int List<T>::clear() { while (0 < _size) { remove(header->succ); //反覆刪除header的後繼 } return 0; } template<typename T>void List<T>::copyNodes(Posi(T)p, int n) { init(); while(n--) { insertAslast(p->data); p = p->succ; } } template<typename T>Posi(T) List<T>::insertAsFirst(T const& e)//作為首元素插入 { return insertA(header,e); } template<typename T>Posi(T) List<T>::insertAslast(T const& e)//作為尾元素插入 { return insertB(trailer,e); } template<typename T>T& List<T>::operator[] (int rank) { Posi(T)p =first();//從首節點出發 while (rank--) p = p->succ; //依次後移 return p->data; //返回資料 } template<typename T>Posi(T) List<T>::find(T const&e,int n,Posi(T)p)//節點p的n個真前驅中找到秩最大的那個 { while (0 < n--) if (e == (p = p->pred)->data)return p; cout << "查詢失敗" << endl; return nullptr; } template<typename T>T List<T>::remove(Posi(T)p) { T temp = p->data; p->pred->succ = p->succ; p->succ->pred = p->pred; delete p; _size--; return temp; } template<typename T>void List<T>::deduplicate() { if (_size < 2)return; Posi(T)p = first(); int rank = 1; while (trailer != (p = p->succ)) { Posi(T)q = find(p->data, rank, p);//在p的r個前驅中找雷同者 q ? remove(q) : rank++; } } template<typename T>void List<T>::traverse()// { Posi(T)p = first(); while (p != trailer) { cout << p->data << ""; p = p->succ; } } template<typename T>void List<T>::selectionSort(Posi(T)p,int n)//選擇排序 { Posi(T)head = p->pred; Posi(T)tail = p; for(int i=0;i<n;i++)tail = tail->succ; while (1 < n) //反覆從待排序區選出最大者,並移至有序區間前端 { insertB(tail, remove(selectMax(head->succ, n))); tail = tail->pred; n--; } } template<typename T>Posi(T) List<T>::selectMax(Posi(T)p, int n) { Posi(T)Max = p; while (1 < n--) { if (Max->data < (p = p->succ)->data)Max = p; } return Max; } template<typename T>int List<T>::uniquify() { int old_size = _size; if (_size < 2)return 0;//平凡連結串列無需去重 Posi(T)temp = first(); while (temp!=trailer) { if (temp->data == (temp->succ)->data) remove(temp->succ); temp = temp->succ; } return old_size-_size; } template<typename T>Posi(T) List<T>::search(T e, int n, Posi(T)p) { while (0<=n--) //--優先順序大於< { if((p=p->pred)->data<=e) break; } return p; } template<typename T>void List<T>::insertSort(Posi(T)p, int n) { for (int r = 0; r < n; r++) { insertA(search(p->data, r, p), p->data);//查詢合適的位置插入 p = p->succ; remove(p->pred);//轉向下一節點 } } template<typename T>void List<T>::merge(Posi(T)&p, int n, List<T>&L, Posi(T)q, int m) { Posi(T)pp = p->pred; while (0 < m) { if (0 < n&&p->data <=q->data) { if((p=p->succ)==q) break; n--; } else { insertB(p, L.remove((q = q->succ)->pred)); m--; } } p = pp->succ;//確定歸併後的新起點 } template<typename T>void List<T>::mergeSort(Posi(T)&p, int n)//一定是傳引用!!! { if (n < 2)return; int m = n >> 1;//以中點為界 Posi(T)q = p; for (int i = 0; i < m; i++)q = q->succ; mergeSort(p, m); mergeSort(q, n - m); merge(p, m, *this, q, n - m);//歸併 } #endif//DSA_LIST_H