資料結構學習筆記之列表
阿新 • • 發佈:2018-12-11
#include <iostream> using namespace std; typedef int Rank; #define Posi(T) ListNode<T>* //列表節點位置 //節點叫法:頭 首 末 尾 template<typename T> struct ListNode { T data; //數值 Posi(T) pred; //前驅 Posi(T) succ; //後繼 ListNode() {} //針對header和trailer的構造 ListNode(T e, Posi(T) p = NULL, Posi(T) s = NULL) : data(e), pred(p), succ(s) {}//預設構造器 Posi(T) insertAsPred(T const &e);//前插入 Posi(T) insertAsSucc(T const &e);//後插入 }; template<typename T> Posi(T) ListNode<T>::insertAsPred(T const &e) { Posi(T) x = new ListNode(e, pred, this);//新節點的前驅後繼 pred->succ = x;//舊前去的後繼為新節點 pred = x;//this的前驅為新節點 return x;//四個指向完成返回x } template<typename T> Posi(T) ListNode<T>::insertAsSucc(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; //容量 Posi(T) header; //頭節點 Posi(T) trailer;//尾節點 protected: void init();//列表建立時的初始化 void copyNodes(Posi(T) p, int n);//複製構造 int clear();//清空列表 public: List() { init(); } ~List(); void show(); int deduplicate();//無序唯一化 int uniquify();//有序唯一化 T &operator[](Rank r) const;//徇秩訪問,效率低 T remove(Posi(T) p);//刪除節點 Posi(T) first() const { return header->succ; }//首節點位置 Posi(T) last() const { return trailer->pred; }//末節點位置 //以p為根節點,在他的n個真前驅中找e Posi(T) find(T const &e, int n, Posi(T) p) const; //p的n個真前驅中,找到不大於e的最後者 Posi(T) search(T const &e, int n, Posi(T) p) const; Posi(T) insertAsFrist(T const &e);//將e作為首節點插入 Posi(T) insertAsLast(T const &e);//將e作為末節點插入 Posi(T) insertBefore(Posi(T) p, T const &e);//e作為p的前驅插入 Posi(T) insertAfter(Posi(T) p, T const &e);//e作為p的後繼插入 void selectionSort(Posi(T) p, int n);//p後的n個節點選擇排序 Posi(T) selectMax(Posi(T) p, int n);//選出最大值 void insertionSort(Posi(T) p, int n);//p後的n個節點插入排序 }; template<typename T> void List<T>::init() { header = new ListNode<T>;//建立頭哨兵 trailer = new ListNode<T>;//建立尾哨兵 header->succ = trailer; header->pred = NULL; trailer->pred = header; trailer->succ = NULL; _size = 0; } template<typename T> void List<T>::copyNodes(Posi(T) p, int n) { init();//建立頭尾 while(n--)//起自p的n項依次作為末節點插入 { insertAsPred(p->data); p = p->succ; } } template<typename T> int List<T>::clear() { int oldsize = _size; while(0 < _size) remove(header->succ); return oldsize; } template<typename T> List<T>::~List() { clear(); delete header; delete trailer; } template<typename T> int List<T>::deduplicate() { if(_size < 2) return 0; int oldsize = _size; Posi(T) p = first();//從首節點起 Rank r = 1; while(trailer != (p = p->succ)) {//依次查詢每一個元素是否在前驅中存在 Posi(T) q = find(p->data, r, p); q?remove(q):r++;//存在就刪除 } return oldsize - _size; } template<typename T> int List<T>::uniquify() { if(_size < 2) return 0; int oldsize = _size; Posi(T) p = first(); Posi(T) q; while(trailer != (q = p->succ)) if(p->data != q->data)p = q; else remove(q); return oldsize - _size; } template<typename T> T &List<T>::operator[](Rank r) const //&是後加上去的 { Posi(T) p = first(); //從首節點出發 while(0 < r--) p = p->succ; //數出第r個節點 return p->data; } template<typename T> T List<T>::remove(Posi(T) p) { T e = p->data; p->pred->succ = p->succ; p->succ->pred = p->pred; delete p; _size--; return e; } template<typename T> Posi(T) List<T>::find(T const &e, int n, Posi(T) p) const { while(0 < n--) if(e == (p = p->pred)->data) return p; return NULL; } template<typename T> Posi(T) List<T>::search(T const &e, int n, Posi(T) p) const { while(0 <= n--) if(((p = p->pred)->data) <= e) break; return p; } template<typename T> Posi(T) List<T>::insertAsFrist(T const &e) { _size++; return header->insertAsSucc(e); } template<typename T> Posi(T) List<T>::insertAsLast(T const &e) { _size++; return trailer->insertAsPred(e); } template<typename T> Posi(T) List<T>::insertBefore(Posi(T) p, T const &e) { _size++; return p->insertAsPred(e); } template<typename T> Posi(T) List<T>::insertAfter(Posi(T) p, T const &e) { _size++; return p->insertAsSucc(e); } 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) { insertBefore(tail, remove(selectMax(head->succ, n))); tail = tail->pred;//每次把最大的放到tail前面,tail前移 n--; } } template<typename T> Posi(T) List<T>::selectMax(Posi(T) p, int n) { Posi(T) max = p; for(Posi(T) cur = p; 1 < n; n--) if(((cur = cur->succ)->data) >= (max->data))//若cur>=max max = cur; return max;//返回最大節點位置 } template<typename T> void List<T>::insertionSort(Posi(T) p, int n) { for (int i = 0; i < n; ++i) {//假想前面有一個區域i,把p插入到i的合適位置,這樣有序的部分一直增大 insertAfter(search(p->data, i, p), p->data); p = p->succ; remove(p->pred); } }//一次插入對應一次銷燬,O(1)輔助空間,原地操 template<typename T> void List<T>::show() { cout<<_size<<"\t"; Posi(T) p = first(); for (int i = 0; i < _size; ++i) { cout<<p->data<<" "; p = p->succ; } cout<<endl; } int main(int argc, char const *argv[]) { List<int> a; a.insertAsFrist(1); a.insertAsLast(9); a.insertBefore(a.first(), 0); a.insertAfter(a.last(), 19); a.insertBefore(a.first(), 9); a.insertAfter(a.last(), 1); a.deduplicate(); a.show(); cout<<a.find(1, 1, a.last())<<endl; a.insertBefore(a.first(), 0); a.insertAfter(a.last(), 19); a.insertBefore(a.first(), 9); a.insertAfter(a.last(), 1); a.show(); a.insertionSort(a.first(), 8); a.show(); return 0; }