資料結構學習(C++)——雙向連結串列 (轉)
原書這部分內容很多,至少相對於迴圈連結串列是很多。相信當你把單連結串列的指標域搞清楚後,這部分應該難不倒你。現在我的問題是,能不能從單連結串列派生出雙向連結串列?:namespace prefix = o ns = "urn:schemas--com::office" />
你可以有幾種做法:
一種就是先定義一個雙鏈節點——但是,它的名字必須叫Node,這是沒辦法的事;不然你就只好複製一份單連結串列的實現,把其中的Node全都替換成你的雙鏈節點名字,但是這就不叫繼承了。
另一種做法就是先定義一種結構例如這樣的:
template
{
public:
Type data;
Node
}
當你派生雙向連結串列時,這樣寫template
在開始完成你的從單連結串列派生出來的雙向連結串列之前,要在單連結串列這個基類中新增修改當前指標和當前前驅指標的介面,如下所示:
protected:
void Put(Node
{
current = p;
}
void PutPrior(Node
{
prior = p;
}
因為這個介面很危險,而且幾乎用不到,所以我在前面並沒有給出,但要完成雙向連結串列最“傑出”的優點——向前移動當前指標,必須要使用。另外說的是,我從前也從來沒計劃從單連結串列派生雙連結串列,下面你將看到,這個過程很讓人煩人,甚至不如重寫一個來的省事,也不是很好,這種費力不討好的事做它有什麼意思呢?的確,我也覺得我在鑽牛角尖。(別拿雞蛋丟我)
定義和實現
#ifndef DblList_H
#define DblList_H
#include "List.h"
template
{
public:
Type *Get()
{
if (pGet() != NULL) return &pGet()->data.data;
else return NULL;
}
Type *Next()
{
pNext();
return Get();
}
Type *Prior()
{
if (pGetPrior != NULL)
{
Put(pGetPrior());
PutPrior( (Node< Node
return Get();
}
return NULL;
}
void Insert(const Type &value)
{
Node
List< Node
if (pGetNext()->link != NULL)
pGetNext()->link->data.link = (Node
}
BOOL Remove()
{
if (List< Node
{
pGet()->data.link = (Node
return TURE;
}
return FALSE;
}
};
#endif
【說明】只完成了最重要的Insert和Remove函式和最具特點的Prior()函式,其他的沒有重新實現。所以,你在這裡使用單連結串列的其他方法,我不保證一定正確。並且,這裡的指標型別轉換依賴於實現,我也不能肯定其他的編譯器編譯出來也能正確。對於讓不讓Prior返回頭節點的data,我考慮再三,反正用First();Get();這樣的組合也能返回,所以就不在乎他了,所以要是用Prior遍歷直到返回NULL,就會將頭節點的data輸出來了。
【補充】至於雙向迴圈連結串列,也可以從這個雙向連結串列派生(仿照派生迴圈連結串列的方法);或者從迴圈連結串列派生(仿照派生雙向連結串列的方法),就不一一舉例了(再這樣下去,我就真鬧心的要吐血了)。至此,可以得出一個結論,連結串列的各種結構都是能從單連結串列派生出來的。換句話說,單連結串列是根本所在,如果研究透了單連結串列,各種鏈式結構都不難。
一小段測試
void DblListTest_int()
{
DblList
for (int i = 10; i > 1; i--) a.Insert(i);
for (i = 10; i > 1; i--) cout << *a.Next() << " ";
a.First();
cout << endl;
cout << *a.Next() << endl;
cout << *a.Next() << endl;
cout << *a.Next() << endl;
cout << *a.Next() << endl;
a.Remove();
cout << *a.Get() << endl;
cout << *a.Prior() << endl;
cout << *a.Prior() << endl;
cout << *a.Prior() << endl;
}
【後記】從我對雙向連結串列不負責任的實現來看,我並不想這麼來實現雙向連結串列,我只是嘗試怎樣最大限度的利用已有的類來實現這種型別。實踐證明,不如重寫一個。別人看起來也好看一些,自己寫起來也不用這樣鬧心。不過,這個過程讓我對函式的和返回的理解又更深了一步。如果你能第一次就寫對這裡的Insert函式,相信你一定對C++有一定的感觸了。我也覺得,只有做一些創新,才能最已經很成熟的東西更深入的瞭解。比如,這些資料結構,在C++的標準庫(STL)中都可以直接拿來用,我們為什麼還辛辛苦苦的寫,結果還不如人家原來的好。為了學習,這就是理由,這也是一切看起來很笨的事發生的理由。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752019/viewspace-981175/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 資料結構——雙向連結串列資料結構
- 資料結構--陣列、單向連結串列、雙向連結串列資料結構陣列
- 資料結構之雙向連結串列資料結構
- 資料結構實驗之連結串列九:雙向連結串列資料結構
- 資料結構(雙向連結串列的實現)資料結構
- 資料結構-雙向連結串列(Python實現)資料結構Python
- 資料結構-單連結串列、雙連結串列資料結構
- Java學習筆記:資料結構之線性表(雙向連結串列)Java筆記資料結構
- 畫江湖之資料結構【第一話:連結串列】雙向連結串列資料結構
- 畫江湖之資料結構 [第一話:連結串列] 雙向連結串列資料結構
- 資料結構學習--連結串列資料結構
- 【資料結構與演算法學習】線性表(順序表、單連結串列、雙向連結串列、迴圈連結串列)資料結構演算法
- 連結串列-雙向連結串列
- 資料結構與演算法——連結串列 Linked List(單連結串列、雙向連結串列、單向環形連結串列-Josephu 問題)資料結構演算法
- 連結串列-雙向通用連結串列
- LVGL雙向連結串列學習筆記筆記
- 結構與演算法(03):單向連結串列和雙向連結串列演算法
- python演算法與資料結構-雙向連結串列(40)Python演算法資料結構
- 連結串列-雙向非通用連結串列
- 雙向連結串列
- 學習 JavaScript 資料結構(二)——連結串列JavaScript資料結構
- 資料結構之連結串列:206. 反轉連結串列資料結構
- C語言資料結構:雙向連結串列的增刪操作C語言資料結構
- 畫江湖之資料結構【第一話:連結串列】單向連結串列資料結構
- 畫江湖之資料結構 [第一話:連結串列] 單向連結串列資料結構
- C++資料結構連結串列的基本操作C++資料結構
- 資料結構 - 單連結串列 C++ 實現資料結構C++
- 深入理解Redis 資料結構—雙連結串列Redis資料結構
- 【C++ 資料結構:連結串列】二刷LeetCode707設計連結串列C++資料結構LeetCode
- 資料結構 - 連結串列資料結構
- 連結串列-資料結構資料結構
- 資料結構—連結串列資料結構
- 資料結構--連結串列資料結構
- 資料結構-連結串列資料結構
- C語言資料結構:雙向迴圈連結串列的增刪操作C語言資料結構
- 資料結構與演算法(三) -- 線性表之雙向連結串列資料結構演算法
- 實現雙向連結串列
- JS資料結構第三篇---雙向連結串列和迴圈連結串列之約瑟夫問題JS資料結構
- 資料結構之php實現單向連結串列資料結構PHP