1,完成鏈式儲存結構線性表的實現;
2,linklist 設計要點:
1,類模板,通過頭結點訪問後繼結點;
2,定義內部結點型別 node,用於描述資料域和指標域;
3,實現線性表的關鍵操作(增刪查等);
3,鍊錶的定義:
4,linklist 鍊錶的實現:
15,問題:#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
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實現 鏈式儲存(單向鍊錶)
單向鍊錶 單鏈表 是鍊錶的一種,其特點是鍊錶的鏈結方向是單向的,對鍊錶的訪問要通過順序讀取從頭部開始。鏈式儲存結構的線性表將採用一組任意的儲存單元存放線性表中的資料元素。由於不需要按順序儲存,鍊錶在插入 刪除資料元素時比順序儲存要快,但是在查詢乙個節點時則要比順序儲存要慢。使用鏈式儲存可以克服順序線...