詳談線性表中帶頭節點與不帶頭結點連結串列
之前給別人講解過線性表這一資料結構,發現很多人在引入線性表的控制頭後就把控制頭指標與不帶頭節點連結串列的連結串列頭指標混淆了,其實造成這一誤區的根本原因還是對於帶頭節點連結串列與不帶頭節點連結串列的本質不夠清楚。本文會通過線性表資料結構實現方式與線性表類的區別作為切入點,詳細解釋帶頭結點連結串列與不帶頭結點連結串列的區別。
首先我們區別三個概念:線性表,連結串列,連結串列類。
線性表是一種資料結構,表示資料之間的關係呈線性關係的一系列資料集合。這是一種抽象的概念,是用來描述資料之間的關係的。我們可以用陣列的方式實現這種資料結構,也可以用我們今天講到的連結串列的方式實現。
連結串列是線性表的一種實現手段,具體實現方法不在本文中詳細講述,本文重點放在區分幾個概念上。
連結串列類包含在連結串列的基礎上再增加一系列對於連結串列的屬性的描述以及針對該連結串列的一系列操作。
下面我們用一幅圖來描述三者之間的關係:
從中我們不難理解,我們在學習C語言時所學的連結串列只是一種實現手段,因此,帶頭結點連結串列與不帶頭節點連結串列的討論應該集中在連結串列的實現手段上,而這兩種實現手段的區別就在於該連結串列的頭部究竟是一個指向連結串列節點型別的資料的一個指標(指類為結構體型別的指標型別),還是一個連結串列節點型別的資料(結構體型別)並用該結構體的next成員儲存第一個資料節點的首地址值。
上文所說的是連結串列的實現手段,它在連結串列類中扮演的是圖中用藍色線框出的那一部分,它是連結串列類的主體,也可以叫做核心,其他的資料,例如length、maxLength... ...以及一些圖中沒有畫出的基於連結串列的一系列操作:如,建立連結串列、銷燬連結串列、增、刪、查詢等等都是基於該連結串列主體的屬性的描述以及基於該連結串列主體需要實現的操作。這時連結串列頭(head)僅僅作為連結串列類裡的一個成員,我在圖中沒有標明這個“head”是什麼型別,就是為了說明這個“head”的型別是由連結串列的實現方式決定的。
這時我們就要講到另一個容易混淆的概念了,那就是連結串列類的總控制頭和連結串列頭。這樣的問題只會存在於C語言中,因為C語言沒有給出類這樣的工具,只有通過結構體和指標相結合的方式來實現類。從圖中我們可以看出有一個LINK_LIST *型別的資料指向了一個LINK_LIST型別的資料,而這個LINK_LIST型別的結構體才是真正的連結串列類。由於我們在使用這一型別的時候免不了要修改其中的資料,因此我們要使用該結構體時必須通過該結構體的指標間接訪問(如果該處不理解,請先複習C語言函式的形參與實參),因此,該LINK_LIST *型別的資料就是我們所說的連結串列類的總控制頭。