演算法 資料結構 鍊錶和哨兵節點

2021-09-12 06:47:21 字數 2396 閱讀 1794

鍊錶是一種基礎的資料結構,但對於一些初學者來說,實現乙個鍊錶還是比較困難的,許多操作作用在頭部或尾部時需要特殊處理。比如下面這段**:

template

<

typename t>

void linkedlist

::remove

(linkedlistnode

* node)

上述**進行了兩次的空值判斷,有可能會更新煉表頭節點,比較複雜,容易出現遺漏。如果在實現鍊錶的時候借助哨兵節點,則可以有效降低**量和**邏輯的複雜程度。

在鍊錶和其它類似資料結構中,資料都儲存在節點中。哨兵節點是一種不儲存任何資料的節點,用法非常靈活,一般被用來標識資料結構的頭尾或沒有節點的情況。下面給出乙個帶哨兵節點的鍊錶實現。

c++**:

template

<

typename t>

struct linkedlistnode

linkedlistnode

(t val, linkedlistnode

* prev =

nullptr

, linkedlistnode

* succ =

nullptr)}

;template

<

typename t>

struct linkedlist

linkedlistnode

*insert

(linkedlistnode

* prev, t val)

//在prev節點後插入val值

linkedlistnode

*insert

(t val)

//在鍊錶頭部插入val值

void

remove

(linkedlistnode

* node)

//在鍊錶中刪除node節點

linkedlistnode

*get

(int index)

//返回鍊錶index位置的節點

t &operator

(int index)

//過載運算子

};

在鍊錶中我們使用了兩個哨兵節點,分別標識鍊錶的頭和尾。哨兵節點在鍊錶建立的時候就存在了,並且對外部是不可見的,因此這兩個哨兵節點會始終標識鍊錶的頭和尾,不可能有節點出現在頭哨兵節點之前,也不可能有節點出現在尾哨兵節點之後。鍊錶中至少會包含兩個哨兵節點,不會出現空鍊錶的情況。

可以看出,在使用了哨兵節點之後,**量和**邏輯的複雜程度都大大降低。還是以remove方法為例。

不使用哨兵節點:

template

<

typename t>

void linkedlist

::remove

(linkedlistnode

* node)

使用哨兵節點

template

<

typename t>

void linkedlist

::remove

(linkedlistnode

* node)

使用哨兵節點減少了兩次對空值的判斷。

現在我們已經知道使用哨兵節點會降低**量和**邏輯的複雜程度,但原因是什麼呢?

從本質上來看,哨兵節點不儲存任何資料,僅作為乙個標識,一般出現在原本應該為空值的地方。比如說不使用哨兵節點的鍊錶的第乙個節點,其前驅節點的值一般為nullptr,使用哨兵節點之後,其前驅節點就是頭哨兵節點。用哨兵節點代替空值,這樣會帶來兩個好處:

(1) 省去判斷空值。如果不使用哨兵節點,那麼就經常需要在使用乙個指標之前,判斷其是否為空。

(2) 避免出現空資料結構的情況。對於鍊錶和其它類似的資料結構,空資料結構的處理比較麻煩,因為向空資料結構中插入第乙個資料的時候,需要給一些屬性賦值(對於鍊錶來說這個屬性就是頭節點,對於某些樹來說這個屬性則是根),而向非空資料結構中插入資料時則不需要賦值,這就導致了進行插入操作時需要分類討論,先判斷資料結構是否為空。同理,刪除操作也存在類似問題,需要判斷刪除後資料結構是否為空。

雖然哨兵節點有很多好處,但依舊存在乙個弊端。哨兵節點往往替代的是空節點,而空節點不占用空間,因此使用哨兵節點實現資料結構,相比不使用哨兵節點的實現,總是要多占用一些空間。具體對空間效率的影響程度,要看哨兵節點的個數相對於總節點個數的佔比,佔比越高則影響越大。

在資料結構中使用哨兵節點有助於降低**量和**邏輯的複雜程度。

哨兵節點降低**量和**邏輯複雜程度的原因在於:省去判斷空值和避免出現空資料結構的情況。

使用哨兵節點有可能會影響空間效率。

哨兵節點不止在鍊錶中使用,還有很多資料結構可以使用哨兵節點,比如二叉搜尋樹。

演算法 資料結構篇 陣列和鍊錶

演算法和資料結構都是非常基礎的內容,經常使用,但是又很容易被忽視,而被重視的時候往往是面試官提問的時候。之前很不理解為什麼面試官總喜歡問演算法和資料結構,日常價值不大的東西。後來隨著工作的深入,越發的理解 演算法 資料結構 程式 之所以後來理解了這個公式,系統學過演算法和資料結構的知識,清楚的知道它...

資料結構與演算法 資料結構之雙向鍊錶

雙向鍊錶自我感覺修改的時候有點繞,不過還好,如果實在不理解一定記得畫圖,其實很容易,但是想出來容易漏掉一些步驟,總之就是多動手 package org.yc public class test class doublelinkedlistheadelse temp.next studentnode ...

演算法(資料結構)

空間不夠儲存 給40億個不重複的unsigned int的整數,沒排過序的,然後再給乙個數,如何快速判斷這個數是否在那40億個數當中 40億個數空間儲存的問題 利用對映 分析 unsigned 範圍是2 32 40億大約大約4g個數不到,常規方法肯定是不行的 我們你可以利用 伴隨陣列 那種思想利用記...