線性表的鏈式儲存 單鏈表的實現

2022-08-18 01:21:14 字數 4042 閱讀 4826

1,完成鏈式儲存結構線性表的實現;

2,linklist 設計要點:

1,類模板,通過頭結點訪問後繼結點;

2,定義內部結點型別 node,用於描述資料域和指標域;

3,實現線性表的關鍵操作(增刪查等);

3,鍊錶的定義:

4,linklist 鍊錶的實現:

1

#ifndef linklist_h

2#define linklist_h

34 #include "

list.h

"5 #include "

exception.h"6

7/*鍊錶三要素:長度、頭結點、指標域。 */8

namespace

dtlib9;

20/*

設法在構造頭結點的時候,不去構造泛指型別的建構函式;以免泛指型別有異常產生,而此刻如果只是定義鍊錶物件沒有插入資料的話,就會構造鍊錶物件的成員變數頭結點、此時頭結點就會呼叫普通結點中構造泛指型別的建構函式來構造頭結點物件,從而產生異常;捨棄了 node* m_header 的構造方式

*/21

22    mutable struct : public object //

構造頭結點的時候,設法不去呼叫泛指型別的函式;構造匿名型別的結構,為了保證結構相同,這裡也繼承了object,因為 object 中有虛函式,這樣也會改變子類的結構的,此時不繼承的話 reinterpret_cast解釋 m_header 和 node 的不同呢,就會有異常產生;

23m_header; //

頭結點物件在記憶體布局上面和上面結構node結構體沒有任何差異,有差異僅在於不管t為何物件,都不會呼叫t的建構函式(如果有);

2728

int m_length; //

定義鍊錶的長度

29 node* m_current; //

定義遍歷函式當前游標的位置

30int m_step; //

定義遍歷函式遍歷的步幅,這裡實

//質是通過成員變數 m_step 將 move() 中的引數 setp 傳遞到 next()中來控制移動的步幅;

3132 node* position(int i) const

//o(n) 第 i 個節點,但是下標為 i - 1

3340

41return

ret;42}

4344

virtual node* creat() //

這樣的封裝是因為物件導向裡面的主導思想有封裝,所以採納這樣的封裝;在 linklist 中沒有多大意義,但對於後續學習有很大的意義,更有利於增強擴充套件性

4548

49virtual

void destroy(node* pn) //

這樣的封裝是因為物件導向裡面的主導思想有封裝,所以採納這樣的封裝;在 linklist 中沒有多大意義,但對於後續學習有很大的意義,更有利於增強擴充套件性

5053

54public:55

linklist()

5662

63bool insert(const t& e) //

6467

68bool insert(int i, const t& e) //

(n) 實現步驟和線性表大同小異

6985

else

8689}90

91return

ret;92}

9394

bool remove(int i) //

o(n)

95107

108 current->next = todel->next;

109 m_length--;

110destroy(todel);

111}

112113

return

ret;

114}

115116

bool

set(int i, const t&e)

117124

125return

ret;

126}

127128

virtual t get(int i) const

129136

else

137140

141return

ret;

142}

143144

bool

get(int i, t& e) const

//const 表明不能夠修改任何成員變數的值;

145152

153return

ret;

154}

155156

int find(const t& e) const

//發現當前值為 e 的節點所處的鍊錶 位置 i ;

157169

else

170174

}175

176return

ret;

177}

178179

int length() const

//o(1)

180183

184void clear() //

o(n)

185193

}194

195/*

以下四個函式move(),end(),next(),current()是為了將遍歷輸出函式時間複雜度由o(n*n)降為o(n);其中 move() 函式時間複雜度為 i,其後三個函式在 for() 迴圈中加起來的時間複雜度為才為 o(n),很經典

*/196

197virtual

bool move(int i, int step = 1) //

從第 i 個位置移動,每次移動 1 個位置; o(n)

198206

return

ret;

207}

208209

virtual

bool end() //

判斷當前的游標是否結束

210213

214virtual t current() //

獲取游標當前位置的值

215220

else

221224

}225

226virtual

bool next() //

移動游標

227235

236return (i ==m_step);

237}

238239 ~linklist() //

o(n)

240243

};244

}245

#endif

//linklist_h

5,問題:

1,頭結點是否存在隱患?

1,設法在構造頭結點的時候,不去構造泛指型別的建構函式;以免泛指型別有異常產生,而此刻如果只是定義鍊錶物件沒有插入資料的話,就會構造鍊錶物件的成員變數頭結點、此時頭結點就會呼叫普通結點中構造泛指型別的建構函式來構造頭結點物件,從而產生異常;

2,用匿名結構體加上佔位空間來解決問題,見 5 中**實現;

2,實現**是否需要優化?

1,insert、remove、get、set 等操作都涉及元素定位;

6,小結:

1,通過類模板實現鍊錶,包含頭結點成員和長度成員;

2,定義節點型別,並通過堆中的結點隊形構成鏈式儲存;

3,為了避免構造錯誤的隱患,頭結點型別需要重定義;

4,**優化是編碼完成後必不可少的環節;

線性表的鏈式儲存 單鏈表

邏輯結構上乙個挨著乙個的資料,在實際儲存中,並沒有像順序表那樣也相互緊挨著,恰恰相反,資料隨機分布在記憶體的各個位置,這種儲存結構稱為線性表的鏈式儲存。由於分散儲存,為了能夠體現出資料元素之間的邏輯關係,每個資料元素在儲存的同時,要配備乙個指標,用於指向它的直接後繼元素,即每乙個資料元素都指向下乙個...

線性表的鏈式儲存 單鏈表

forward list creat 3 頭插法 return head 尾插法建表 forward list creat 1 if rear null 對於非空表,將尾結點的下乙個結點置空 rear next null return head 尾插法建表,包含頭結點 forward list cr...

線性表的Java實現 鏈式儲存(單向鍊錶)

單向鍊錶 單鏈表 是鍊錶的一種,其特點是鍊錶的鏈結方向是單向的,對鍊錶的訪問要通過順序讀取從頭部開始。鏈式儲存結構的線性表將採用一組任意的儲存單元存放線性表中的資料元素。由於不需要按順序儲存,鍊錶在插入 刪除資料元素時比順序儲存要快,但是在查詢乙個節點時則要比順序儲存要慢。使用鏈式儲存可以克服順序線...