日本免费全黄少妇一区二区三区-高清无码一区二区三区四区-欧美中文字幕日韩在线观看-国产福利诱惑在线网站-国产中文字幕一区在线-亚洲欧美精品日韩一区-久久国产精品国产精品国产-国产精久久久久久一区二区三区-欧美亚洲国产精品久久久久

數(shù)據(jù)結(jié)構(gòu) - 鏈表

數(shù)據(jù)結(jié)構(gòu) - 鏈表

文章圖片

數(shù)據(jù)結(jié)構(gòu) - 鏈表

文章圖片

數(shù)據(jù)結(jié)構(gòu) - 鏈表

文章圖片

數(shù)據(jù)結(jié)構(gòu) - 鏈表

文章圖片

數(shù)據(jù)結(jié)構(gòu) - 鏈表

文章圖片

數(shù)據(jù)結(jié)構(gòu) - 鏈表

文章圖片

數(shù)據(jù)結(jié)構(gòu) - 鏈表

文章圖片

數(shù)據(jù)結(jié)構(gòu) - 鏈表

文章圖片

數(shù)據(jù)結(jié)構(gòu) - 鏈表

文章圖片

數(shù)據(jù)結(jié)構(gòu) - 鏈表

今天我們將開始第二個(gè)數(shù)據(jù)類型-鏈表的學(xué)習(xí) , 同樣我們還是用最原始的方式 , 自己申請(qǐng)內(nèi)存管理內(nèi)存來實(shí)現(xiàn)一個(gè)鏈表 。

01、定義什么是鏈表?鏈表在物理存儲(chǔ)結(jié)構(gòu)上表現(xiàn)為非順序性和非連續(xù)性 , 因此鏈表的數(shù)據(jù)元素物理存儲(chǔ)位置是隨機(jī)的 , 動(dòng)態(tài)分配的;而在邏輯結(jié)構(gòu)上表現(xiàn)為線性結(jié)構(gòu)的特點(diǎn) , 即元素一個(gè)連著一個(gè)元素串起來像一條線\t 。
節(jié)點(diǎn):其中鏈表元素又叫節(jié)點(diǎn) , 一個(gè)節(jié)點(diǎn)主要包含數(shù)據(jù)域和指針域 , 其中數(shù)據(jù)域主要存放數(shù)據(jù)元素 , 而指針域主要存放下一個(gè)節(jié)點(diǎn)存儲(chǔ)位置地址 。
頭指針:一個(gè)表示鏈表第一個(gè)節(jié)點(diǎn)位置的普通指針 , 并且永遠(yuǎn)指向第一個(gè)節(jié)點(diǎn)位置 , 方便后面使用鏈表 。
頭節(jié)點(diǎn):通常表示鏈表的第一個(gè)節(jié)點(diǎn) , 并且節(jié)點(diǎn)內(nèi)數(shù)據(jù)域?yàn)榭?, 因此也叫空節(jié)點(diǎn) , 其作用主要用于解決一些特殊問題 , 因此也可以省略 。
首元節(jié)點(diǎn):由于頭節(jié)點(diǎn)數(shù)據(jù)域?yàn)榭?, 因此鏈表的第一個(gè)數(shù)據(jù)域不為空的節(jié)點(diǎn)叫首元節(jié)點(diǎn) , 只是一個(gè)名稱 , 并沒有什么實(shí)際意義 。

02、分類鏈表有兩種分類方法 , 其一可以分為靜態(tài)鏈表和動(dòng)態(tài)鏈表 , 其二可以分為單向鏈表、雙向鏈表以及循環(huán)鏈表 。
單鏈表只有一個(gè)方向 , 每個(gè)節(jié)點(diǎn)包含數(shù)據(jù)域和指向下一個(gè)節(jié)點(diǎn)的指針域 。

雙向鏈表有兩個(gè)方向 , 即每個(gè)節(jié)點(diǎn)包含數(shù)據(jù)域以及同時(shí)指向上一個(gè)節(jié)點(diǎn)和下一個(gè)節(jié)點(diǎn)的指針域 。

循環(huán)鏈表指鏈表首尾相連 , 即最后一個(gè)節(jié)點(diǎn)的指針域指向第一個(gè)節(jié)點(diǎn) 。 循環(huán)鏈表也分單向循環(huán)鏈表和雙向循環(huán)鏈表 , 原理都一樣 。

03、實(shí)現(xiàn)下面我們一起使用最原始的方式 , 自己申請(qǐng)內(nèi)存空間 , 自己維護(hù) , 完成鏈表的實(shí)現(xiàn) 。
1、ADT定義我們首先來定義鏈表的ADT(單鏈表) 。
ADT LinkedList{
數(shù)據(jù)對(duì)象:D 是一個(gè)非空的元素集合 , D = {a1 a2 ... an , 其中 ai 表示一個(gè)元素即節(jié)點(diǎn) , 一個(gè)節(jié)點(diǎn)存儲(chǔ)著數(shù)據(jù)和指向下一個(gè)節(jié)點(diǎn)的指針 。
數(shù)據(jù)關(guān)系:D中的節(jié)點(diǎn)通過指針進(jìn)行連接 , 每一個(gè)節(jié)點(diǎn)都包含一個(gè)指向下一個(gè)節(jié)點(diǎn)的指針 。
基本操作:[
Init(n) :初始化一個(gè)空鏈表 , 即聲明一個(gè)頭指針 , 如有必要也可以聲明一個(gè)頭節(jié)點(diǎn) 。
Length:返回鏈表長(zhǎng)度 。
HeadNode:返回頭節(jié)點(diǎn) 。
Find(v):返回?cái)?shù)據(jù)域v對(duì)應(yīng)的節(jié)點(diǎn) 。
Update(nv):更新n節(jié)點(diǎn)的數(shù)據(jù)域 。
InsertAfter(nv):在n節(jié)點(diǎn)后面添加數(shù)據(jù)域?yàn)関的新節(jié)點(diǎn) 。
Remove(n):移除n節(jié)點(diǎn) 。
Destroy():銷毀鏈表 。



定義好鏈表ADT , 下面我們就可以開始自己實(shí)現(xiàn)一個(gè)數(shù)據(jù)域?yàn)閟tring類型的鏈表 。
2、定義類首先我們需要定義節(jié)點(diǎn) , 其中包含兩個(gè)字段一個(gè)是存放數(shù)據(jù)、一個(gè)是存放指針代碼如下 。

然后再定義鏈表實(shí)現(xiàn)類MyselfLinkedList , 用來實(shí)現(xiàn)鏈表的相關(guān)操作 。

因?yàn)槲覀冎苯庸芾韮?nèi)存 , 所以需要一個(gè)維護(hù)內(nèi)存的指針字段;
因?yàn)槲覀冎苯荧@取鏈表長(zhǎng)度 , 所以需要一個(gè)存儲(chǔ)鏈表長(zhǎng)度字段;
因此我們的MyselfLinkedList類初步是這樣的:

3、初始化Init初始化結(jié)構(gòu)主要做幾件事 。
a.分配內(nèi)存空間;
b.什么頭指針;
c.創(chuàng)建頭節(jié)點(diǎn);
d.維護(hù)鏈表長(zhǎng)度屬性;
具體實(shí)現(xiàn)代碼如下:

4、獲取鏈表長(zhǎng)度 Length這個(gè)比較簡(jiǎn)單直接把鏈表長(zhǎng)度私有字段返回即可 。

5、獲取頭節(jié)點(diǎn) HeadNode獲取頭節(jié)點(diǎn)主要是為了方便數(shù)據(jù)處理 , 可以通過頭指針直接讀取內(nèi)存地址獲取 。 具體代碼如下:

同樣我們也可以定義一個(gè)尾節(jié)點(diǎn)屬性 , 可以方便使用 , 原理都差不多 , 這里就不贅述了 。

6、在指定節(jié)點(diǎn)后插入節(jié)點(diǎn) InsertAfter通過前面對(duì)鏈表結(jié)構(gòu)的了解 , 要想再兩個(gè)節(jié)點(diǎn)之間加入一個(gè)新節(jié)點(diǎn) , 只需要把兩者之間的線剪斷 , 即前一個(gè)節(jié)點(diǎn)的指針域需要重新指向新節(jié)點(diǎn) , 并且新節(jié)點(diǎn)的指針域要指向后一個(gè)節(jié)點(diǎn) , 其他保持不變 , 如下圖:

業(yè)務(wù)邏輯清楚了 , 我們?cè)賮硎崂泶a邏輯 , 要想實(shí)現(xiàn)這個(gè)功能我們大致需要一下幾步:
a.獲取指定節(jié)點(diǎn)的指針;
b.創(chuàng)建一個(gè)新的節(jié)點(diǎn);
c.重新調(diào)整指定節(jié)點(diǎn)及新節(jié)點(diǎn)指針域;
d.把指定節(jié)點(diǎn)和新節(jié)點(diǎn)指針調(diào)整后數(shù)據(jù)更新到內(nèi)存中;
e.更新鏈表長(zhǎng)度屬性;
具體實(shí)現(xiàn)如下:



這里只實(shí)現(xiàn)了一個(gè)在指定節(jié)點(diǎn)后插入節(jié)點(diǎn) , 我們還可以實(shí)現(xiàn)在指定節(jié)點(diǎn)前插入 , 在首元節(jié)點(diǎn)前插入 , 在尾節(jié)點(diǎn)后添加 , 都是可以的 , 感興趣的可以自己實(shí)現(xiàn)試試 。

7、根據(jù)數(shù)據(jù)域查找節(jié)點(diǎn) Find在鏈表中對(duì)查找是不友好的 , 因?yàn)椴檎乙粋€(gè)值 , 需要從鏈表頭一個(gè)一個(gè)往后查找 , 實(shí)現(xiàn)邏輯到不復(fù)雜 , 具體實(shí)現(xiàn)代碼如下:

8、更新指定節(jié)點(diǎn)數(shù)據(jù)域 Update這個(gè)方法邏輯也比較簡(jiǎn)單 , 只需要找到節(jié)點(diǎn)指針 , 然后把節(jié)點(diǎn)更新 , 最后把更新后的數(shù)據(jù)寫入內(nèi)存即可 。

9、移除指定節(jié)點(diǎn) Remove如果要想移除一個(gè)節(jié)點(diǎn) , 則需要把指定節(jié)點(diǎn)與前后節(jié)點(diǎn)的連接刪除 , 然后把前后兩個(gè)節(jié)點(diǎn)建立起連接 , 同時(shí)需要手動(dòng)釋放被刪除節(jié)點(diǎn)內(nèi)存 。 如下圖 。

具體代碼實(shí)現(xiàn)如下:

10、銷毀鏈表 Destroy銷毀鏈表主要是使用因?yàn)槭俏覀冏约菏謩?dòng)管理內(nèi)存 , 用完后要及時(shí)清理 , 放在內(nèi)存泄漏等意外情況出現(xiàn) 。 代碼也很簡(jiǎn)單 , 循環(huán)把每個(gè)節(jié)點(diǎn)內(nèi)存釋放即可 , 如下代碼:

11、釋放內(nèi)存 Dispose因?yàn)槲覀儗?shí)現(xiàn)了IDisposable接口 , 所有需要實(shí)現(xiàn)Dispose方法 , 只需要在Dispose方法中調(diào)用上面銷毀鏈表Destroy方法即可 。
【數(shù)據(jù)結(jié)構(gòu) - 鏈表】注:測(cè)試方法代碼以及示例源碼都已經(jīng)上傳至代碼庫 , 有興趣的可以看看 。 https://gitee.com/hugogoos/Planner

    推薦閱讀