雙向鍊錶的GO語言實現

2021-09-14 05:42:42 字數 3682 閱讀 2023

一、什麼是雙向鍊錶

和單鏈表比較,雙向鍊錶的元素不但知道自己的下線,還知道自己的上線(越來越像傳銷組織了)。小煤車開起來,圖裡面可以看出,每個車廂除了乙個指向後面車廂的箭頭外,還有乙個指向前面車廂的箭頭(車頭、車尾除外)。車頭只有指向後面車廂的箭頭,車尾只有指向前面車廂的箭頭。

二、雙向鍊錶與go的對應結構

1、節點

我們先把車廂分解開來。每節車廂都由煤炭、車體、拉前車廂繩索、拉後車廂繩索這4部分組成。車體是我們的運輸工具,在go語言裡我們用結構提dnode表示;煤炭代表運的貨物,用data變數表示;拉前車廂繩索和拉後車廂繩索我們分別用指標prev和next表示。這樣一節車廂,用go語言描述如下:

type dnode struct
2、雙向鍊錶

乙個運煤車隊就是乙個雙向鍊錶。車隊要有車頭、車廂、車尾,作為車隊的負責人還得知道車隊有多長。在go語言裡,車隊用結構體dlist表示,車頭用head變數表示,車位用tail變數表示,車隊長度就用size來表示,把這些表示合起來:

type dlist struct
結構講完了,下面講講如何增加、減少車廂,也就是雙向鍊錶的介面。

三、介面說明及實現

介面主要分為這幾類。乙個是雙向鍊錶本身的,還有一類是節點的。鍊錶本身的還分為公開和私有兩種。下面我們就詳細聊聊這些介面。

1、初始化鍊錶init

雙向鍊錶的初始化,可以理解成大衛哥準備買乙個車隊準備運煤。第一步,得獲得國家有關部門的批准,有了批准大衛哥就可以買車廂運煤了。但是,批准下來的時候,大衛哥的車隊啥都沒有,沒有車頭、車尾,連一節車廂也沒有。go語言**實現:

func (dlist *dlist) init()
大衛哥新買了車廂,買好的車廂要掛到車隊後面。第一節車廂就是車頭。

newnode := new(dnode)

(*newnode).data = data

if (*dlist).getsize() == 0 else

(*dlist).size++;}

3、在節點後面插入資料insertnext

有時候,車廂不是放在車隊尾巴,而是要放在中間,比如都是運蘋果的車廂最好放一起。

func (dlist *dlist) insertnext(elmt *dnode, data object) bool 

if dlist.istail(elmt) else

return true

}

5、在節點前面插入資料insertprev在節點前面插入資料,可以理解為在當前節點前乙個節點的後面插入資料。

func (dlist *dlist) insertprev(elmt *dnode, data object) bool 

if dlist.ishead(elmt) else

}

這裡的ishead就是判斷節點是否是車頭,後面大衛哥會介紹。

6、刪除乙個節點remove

有些車廂出現問題需要維修,就要把它從車隊裡卸下來。

func (dlist *dlist) remove(elmt *dnode) object 

prev := (*elmt).prev

next := (*elmt).next

if dlist.ishead(elmt) else

if dlist.istail(elmt) else

dlist.size--

return (*elmt).getdata()

}

卸下來後,車廂裡的資料還是要保留的。

7、查詢指定資料所在的節點search

比如說,要找到蘋果在哪節車廂。就要用到查詢功能了。

func (dlist *dlist) search(data object, yourmatch ...matchfun) *dnode 

match := defaultmatch

if len(yourmatch) > 0

node := dlist.gethead()

for ; node != nil; node = node.getnext()

}return node

}

match是匹配函式,定義如下:

type matchfun func (data1 object, data2 object) int
如果data1和data2相等就返回0,data1大於data2就返回正數,小於就返回負數。

8、獲取鍊錶長度getsize

func (dlist *dlist) getsize() uint64
9、獲取頭部節點gethead

func (dlist *dlist) gethead() *dnode
10、獲取尾部節點gettail

func (dlist *dlist) gettail() *dnode
11、節點是否是頭部節點ishead

func (dlist *dlist) ishead(elmt *dnode) bool
12、節點是否是列表尾部istail

func (dlist *dlist) istail(elmt *dnode) bool
13、獲取節點內資料getdata

func (dnode *dnode) getdata() object
這個是節點的方法,不是鍊錶的。用來獲取車廂內裝的是什麼。

14、獲取下乙個節點getnext

func (dnode *dnode) getnext() *dnode
這個也是節點的方法,幫助車廂找到下一節車廂。

15、獲取前乙個節點getprev

func (dnode *dnode) getprev() *dnode
這裡同樣是節點的方法。用來找到上一節車廂。

go語言實現 雙向迴圈鍊錶

雙向鍊錶也叫雙鏈表,是鍊錶的一種,它的每個資料結點中都有兩個指標,分別指向直接後繼和直接前驅。所以,從雙向鍊錶中的任意乙個結點開始,都可以很方便地訪問它的前驅結點和後繼結點。一般我們都構造雙向迴圈鍊錶。如下 package doublelinkedlist import errors fmt typ...

go語言實現鍊錶

宣告結構體 宣告全域性變數,儲存頭結點 var head node var curr node 宣告節點型別 type node struct 建立頭結點 func createheadnode data string node 新增新節點 func addnode data string node...

Go語言 實現鍊錶

鍊錶是乙個結點指向下乙個結點的儲存結構,每乙個結點有兩個元素,乙個是存放資料本身,另乙個資料指向下乙個結點,由這些結點組成乙個鍊錶 package main import fmt type node struct type nodelist struct func this nodelist add...