原書這部分內容很多,至少相對於迴圈鍊錶是很多。相信當你把單鏈表的指標域搞清楚後,這部分應該難不倒你。現在我的問題是,能不能從單鏈表派生出雙向鍊錶?<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
你可以有幾種做法:
一種就是先定義乙個雙鏈節點--但是,它的名字必須叫node,這是沒辦法的事;不然你就只好拷貝乙份單鏈表的實現檔案,把其中的node全都替換成你的雙鏈節點名字,但是這就不叫繼承了。
另一種做法就是先定義一種結構例如這樣的:
template <class type> class newtype
當你派生雙向鍊錶時,這樣寫template <calss type> class dbllist : public list<newtype<type> >,注意連續的兩個">"之間要有空格。或者根本不定義這樣的結構,直接拿node型別來做,例如我下面給出的。但是,請注意要完成"=="的過載,否則,你又要重寫find函式,並且其他的某些操作也不方便。
在開始完成你的從單鏈表派生出來的雙向鍊錶之前,要在單鏈表這個基類中新增修改當前指標和當前前驅指標的介面,如下所示:
protected:
void put(node<type> *p)//盡量不用,雙向鍊錶將使用這個完成向前移動
void putprior(node<type> *p)//盡量不用,原因同上
因為這個介面很危險,而且幾乎用不到,所以我在前面並沒有給出,但要完成雙向鍊錶最"傑出"的優點--向前移動當前指標,必須要使用。另外說的是,我從前也從來沒計畫從單鏈表派生雙鏈表,下面你將看到,這個過程很讓人煩人,甚至不如重寫乙個來的省事,執行效率也不是很好,這種費力不討好的事做它有什麼意思呢?的確,我也覺得我在鑽牛角尖。
定義和實現
#ifndef dbllist_h
#define dbllist_h
#include "list.h"
template <class type> class dbllist : public list< node<type> >
type *next()
type *prior()
return null;
}void insert(const type &value)
bool remove()
return false;}};
#endif
【說明】只完成了最重要的insert和remove函式和最具特點的prior()函式,其他的沒有重新實現。所以,你在這裡使用單鏈表的其他方法,我不保證一定正確。並且,這裡的指標型別轉換依賴於編譯器實現,我也不能肯定其他的編譯器編譯出來也能正確。對於讓不讓prior返回頭節點的data,我考慮再三,反正用first();get();這樣的組合也能返回,所以就不在乎他了,所以要是用prior遍歷直到返回null,就會將頭節點的data輸出來了。
【補充】至於雙向迴圈鍊錶,也可以從這個雙向鍊錶派生(仿照派生迴圈鍊錶的方法);或者從迴圈鍊錶派生(仿照派生雙向鍊錶的方法),就不一一舉例了(再這樣下去,我就真鬧心的要**了)。至此,可以得出乙個結論,鍊錶的各種結構都是能從單鏈表派生出來的。換句話說,單鏈表是根本所在,如果研究透了單鏈表,各種鏈式結構都不難。---www.bianceng.cn
一小段測試程式
void dbllisttest_int()
資料結構之雙鏈表
前面我們介紹了單鏈表,單鏈表的優點是沒有空間的限制,可以隨意開闢空間。但與我們這次要講的雙鏈表相比,就有點相形見絀了。因為哪怕是單鏈表,在進行查詢 插入 排序等等時都要進行線性表的遍歷,而我們往往需要的是目標節點的前乙個節點,所以經常一不小心就錯過了我們需要的節點,或者經常需要乙個當前節點的備份,以...
資料結構學習(六) 單鏈表
線性表中每個節點有唯一的前趨節點和後繼節點 設計鏈式儲存結構時,每個邏輯節點單獨儲存,為了表示邏輯關係,增加指標域 單鏈表 每個物理節點增加乙個指向後繼節點的指標域 雙鏈表 每個物理節點增加乙個指向後繼節點的指標域和乙個指向前趨節點的指標域 typedef struct lnode 定義單鏈表節點型...
資料結構學習 鍊錶 單鏈表
c語言資料結構之鍊錶 首先呢,開始資料結構中的第乙個部分 線性表 首先我們想到的問題一定是定義乙個結構體變數 定義鍊錶 typedef struct node node 定義好了乙個結構體變數,接下來呢,乙個鍊錶得有個頭,對吧 建立頭節點 node creatheadnode 接下來呢,定義乙個函式...