#ifndef List_H #define List_H #ifndef TURE #define TURE 1 #endif #ifndef FALSE #define FALSE 0 #endiftypedef int BOOL; #include "Node.h" template class List //單鏈表定義 { //基本上無參數的成員函數操作的都是當前節點,即current指的節點 //認為表中“第1個節點”是第0個節點,請注意,即表長為1時,最後一個節點是第0個節點 public: List() { first = current = last = new Node; prior = NULL; } ~List() { MakeEmpty(); delete first; } void MakeEmpty() //置空表 { Node *q; while (first->link != NULL) { q = first->link; first->link = q->link; delete q; } Initialize(); } BOOL IsEmpty() { if (first->link == NULL) { Initialize(); return TURE; } else return FALSE; } int Length() const //計算帶表前端節點的單鏈表長度 { Node *p = first->link; int count = 0; while (p != NULL) { p = p->link; count++; } return count; } Type *Get()//返回當前節點的資料域的地址 { if (current != NULL) return ¤t->data; else return NULL; } BOOL Put(Type const &value)//改變當前節點的data,使其為value { if (current != NULL) { current->data = value; return TURE; } else return FALSE; } Type *GetNext()//返回當前節點的下一個節點的資料域的地址,不改變current { if (current->link != NULL) return ¤t->link->data; else return NULL; } Type *Next()//移動current到下一個節點,返回節點資料域的地址 { if (current != NULL && current->link != NULL) { prior = current; current = current->link; return ¤t->data; } else { return NULL; } } void Insert(const Type &value)//在當前節點的後面插入節點,不改變current { Node *p = new Node(value, current->link); current->link = p; } BOOL InsertBefore(const Type &value)//在當前節點的前面插入一節點,不改變current,改變prior { Node *p = new Node(value); if (prior != NULL) { p->link = current; prior->link = p; prior = p; return TURE; } else return FALSE; } BOOL Locate(int i)//移動current到第i個節點 { if (i <= -1) return FALSE; current = first->link; for (int j = 0; current != NULL && j < i; j++, current = current->link) prior = current; if (current != NULL) return TURE; else return FALSE; } void First()//移動current到表頭 { current = first; prior = NULL; } void End()//移動current到表尾 { if (last->link != NULL) { for ( ;current->link != NULL; current = current->link) prior = current; last = current; } current = last; } BOOL Find(const Type &value)//移動current到資料等於value的節點 { if (IsEmpty()) return FALSE; for (current = first->link, prior = first; current != NULL && current->data != value; current = current->link) prior = current; if (current != NULL) return TURE; else return FALSE; } BOOL Remove()//刪除當前節點,current指向下一個節點,如果current在表尾,執行後current = NULL { if (current != NULL && prior != NULL) { Node *p = current; prior->link = p->link; current = p->link; delete p; return TURE; } else return FALSE; } BOOL RemoveAfter()//刪除當前節點的下一個節點,不改變current { if (current->link != NULL && current != NULL) { Node *p = current->link; current->link = p->link; delete p; return TURE; } else return FALSE; } friend ostream & operator << (ostream & strm, List &l) { l.First(); while (l.current->link != NULL) strm << *l.Next() << " " ; strm << endl; l.First(); return strm; } protected: /*主要是為了高效的入隊演算法所添加的。因為Insert(),Remove(),RemoveAfter()有可能改變last但沒有改變last所以這個演算法如果在public裡除非不使用這些,否則不正確。但是last除了在隊列中非常有用外,其他的時候很少用到,沒有必要為了這個用途而降低Insert(),Remove()的效率所以把這部分放到protected,實際上主要是為了給隊列繼承*/ void LastInsert(const Type &value) { Node *p = new Node(value, last->link); last->link = p; last = p; } void Initialize()//當表為空白表時使指標複位 { current = last = first; prior = NULL; } //這部分函數傳回型別為Node指標,是擴充List功能的介面 Node *pGet() { return current; } Node *pNext() { prior = current; current = current->link; return current; } Node *pGetNext() { return current->link; } Node *pGetFirst() { return first; } Node *pGetLast() { return last; } Node *pGetPrior() { return prior; } void PutLast(Node *p) { last = p; } //這部分插入刪除函數不建立或刪除節點,是原位操作的介面 void Insert(Node *p) { p->link = current->link; current->link = p; } void InsertBefore(Node *p) { p->link = current; prior->link = p; prior = p; } void LastInsert(Node *p) { p->link = NULL; last->link = p; last = p; } Node *pRemove() { if (current != NULL && prior != NULL) { Node *p = current; prior->link = current->link; current = current->link; return p; } else return NULL; } Node *pRemoveAfter() { if (current->link != NULL && current != NULL) { Node *p = current->link; current->link = current->link->link; return p; } else return NULL; } private: List(const List &l); Node *first, *current, *prior, *last; //盡量不要使用last,如果非要使用先用End()使指標last正確 }; #endif |