1. 程式人生 > 實用技巧 >雙鏈表

雙鏈表

1.把雙鏈表這種資料結構的更高一級別抽象(線性表)單獨寫成一個抽象類,然後用於雙鏈表類的繼承,這種寫法可以規範雙鏈表應該有的介面/操作

2.把節點定義為類內的結構體而不是單獨的程式碼顯得更加簡潔。

3.在雙鏈表的插入/刪除/查詢操作中都要找到指向第i個節點的指標,把這個操作統一定義為一個私有的輔助函式move(),可以簡化程式碼

#include <iostream>
using namespace std;

// 線性表:順序表和連結串列共同的抽象類
template<typename elemType>
class list{
public:
    virtual void
clear() = 0; // 刪除線性表中的所有資料元素 virtual int length() const = 0; // 求線性表的長度 virtual void insert(int i, const elemType & x) = 0; // 在第i個位置插入一個元素 virtual void remove(int i) = 0; // 刪除第i個位置的元素 virtual int search(const elemType & x) const
= 0; // 搜尋某個元素x線上性表中是否出現 virtual elemType visit(int i) const = 0; // 返回線性表中第i個數據元素的值 virtual void traverse() const = 0; // 按序訪問線性表的每一資料元素 virtual ~list(){}; }; // 雙鏈表 template<typename elemType> class dLinkList:public list<elemType>{ private: struct
node{ elemType data; node *prev, *next; node(const elemType & x, node* p = NULL, node* n = NULL) {data = x; prev = p; next = n;} node():next(NULL), prev(NULL){} ~node(){} }; node *head, *tail; int currentLength; node* move(int i) const; class NoSuchNodeError{}; public: dLinkList(); ~dLinkList(){clear(); delete head; delete tail;} void clear(); int length() const{return currentLength;} void insert(int i, const elemType & x); void remove(int i); int search(const elemType & x) const; elemType visit(int i) const; void traverse() const; }; template<typename elemType> typename dLinkList<elemType>::node* dLinkList<elemType>::move(int i) const{ node* p = head; while(i-- >= 0) p = p->next; return p; } template<typename elemType> dLinkList<elemType>::dLinkList(){ head = new node; tail = new node; head->next = tail; tail->prev = head; currentLength = 0; } template<typename elemType> void dLinkList<elemType>::clear(){ node* p = head->next; node* q; head->next = tail; tail->prev = head; while(p != tail){ q = p->next; delete p; p = q; } currentLength = 0; } template<typename elemType> void dLinkList<elemType>::insert(int i, const elemType & x){ if(i > currentLength || i < 0) throw NoSuchNodeError(); node* pos = move(i); node* tmp = new node(x, pos->prev, pos); pos->prev->next = tmp; pos->prev = tmp; ++currentLength; } template<typename elemType> void dLinkList<elemType>::remove(int i){ if(i >= currentLength || i < 0) throw NoSuchNodeError(); node* pos = move(i); pos->prev->next = pos->next; pos->next->prev = pos->prev; delete pos; --currentLength; } template<typename elemType> int dLinkList<elemType>::search(const elemType & x) const{ node* p = head->next; int i; for(i = 0; p != tail && p->data != x; ++i) p = p->next; if(p == tail) return -1; else return i; } template<typename elemType> elemType dLinkList<elemType>::visit(int i) const{ if(i >= currentLength || i < 0) throw NoSuchNodeError(); return move(i)->data; } template<typename elemType> void dLinkList<elemType>::traverse() const{ node* p = head->next; while(p != tail){ cout << p->data << " "; p = p->next; } cout << endl; }