學習數據結構--第四章:樹與二叉樹(二叉樹的順序存儲和鏈式存儲)

第四章:樹與二叉樹(二叉樹的存儲結構)

1.二叉樹的順序存儲

二叉樹的順序存儲

用一組連續的存儲單元依次自上而下、自左至右存儲完全二叉樹上的結點元素。

思考爲啥是存儲完全二叉樹?

這裏正常情況存儲的時數據,我們這裏理解就存儲編號了。但是如果使用上圖存儲,我們如何表示二叉樹的邏輯關係呢?

二叉樹的邏輯關係:1 是 2 和 3的雙親結點,2 3 是 1 的孩子結點。

這樣的邏輯關機該如何維護呢?

我們在學習線性表的時候,我們知道線性表的地址是連續的,也就是線性表的下一個結點就是它下一個存儲單元存放的元素,但是如果按照上圖存儲,一個節點的孩子結點一定是它接下來存放的元素嗎?

二叉樹邏輯關係的表示方法:

我們知道:在完全二叉樹中依次編號,對於結點 i :若存在左孩子,則編號爲 2i;若存在右孩子,則編號爲 2i+1 。

所以我們使用這樣的性質來實現二叉樹邏輯關係。

在這裏數組下標和結點的標號是一致的,這樣我們就能使用下標來找到孩子結點下標了。這裏爲了更方便的對應完全二叉樹性質,所以數組的第一個位置我們沒有存儲結點,當然其實也是可以存儲的只不過找孩子結點的方式需要改變:左孩子 2i+1,右孩子2i+2 。其實我們在進行實際應用的是偶,0這個位置是會存儲節點的個數的。

注意上面都是說的是完全二叉樹


例如上圖,是非完全二叉樹,我們按照數組第一個位置空出來然後從上到下,從左到右,將結點依次填入數組,如上圖。此時我們按如果按照上面的性質找3結點的左孩子爲 2x3=6,按理說應該是存儲在下標爲6的地方,可以是實際上存儲到下標爲5的地方,這樣就無法通過之前的方法來表示邏輯關係了。

那麼該採用什麼方法呢?

其實只需要對方法改進一下就行了。我們將這顆非完全二叉樹 完全二叉樹 ,即將 2 號結點補一個右孩子即可,然後進行存放。因爲添加了一個不存在的空結點,所以在數組中用 0 表示

此時就表示了邏輯關係。雖然我們這樣完成了二叉樹的順序存儲的而且表示了邏輯關係,但是這樣的存儲方法是有一個 弊端 的。

如上圖,我們如果將上面的二叉樹使用順序存儲,則需要將其補成完全二叉樹,這樣我們就浪費了很多的存儲空間來進行存放。所以:

順序存儲最壞情況會非常浪費存儲空間,比較適合完全二叉樹

因此我們在存儲二叉樹的時候往往使用鏈式存儲。

2.二叉樹的鏈式存儲

二叉樹的鏈式存儲:用鏈表來存放一棵二叉樹,二叉樹中每個結點用鏈表的一個鏈結點來存儲。

因爲是二叉樹,所以每個結點都可能有一個左孩子和右孩子,我們使用鏈表存放,所以可以每個結點可以定義一個數據域和兩個指針域,兩個指針域用來分別存儲左結點和右結點。

我們舉一個例子來看看具體是如何存放的。

因爲某些結點沒有左孩子或者右孩子,所以會出現空的指針域的情況,關於空指針域的個數我們有如下規律:

含有n個結點的二叉鏈表中,有 n+1 個空鏈域。

上面的結論是通過:2n-(n-1) 這個式子得到。式子的解釋:

2n 表示每一個結點都有兩個指針域,那麼共n個結點,則總共 2n個指針域。我們要想的到空鏈域,則需要減去指針非空指針域。而非空指針域的個數其實就是孩子結點,有一個孩子結點,則需要一個指針域指向,而總共多少個孩子結點呢?總共爲 n-1 個,因爲 n 個結點中除了第一個結點是二叉樹根節點外,其餘都是孩子結點。故得到:2n-(n-1)=n+1

3.總結

本次學習了二叉樹的順序存儲和鏈式存儲,在實際應用中,對於順序存儲我們可能直接在數組的下標爲1的位置開始存儲二叉樹,下標爲0的位置存儲二叉樹的信息。

鏈式存儲中,我們也可能需要三個指針域,除了指向左右孩子結點的指針域,還需要一個指向雙親結點的指針域。

關於數據結構的知識持續更新中,下次將會講解:二叉樹的遍歷和線索二叉樹,歡迎大家的關注,也可以關注同名公衆號 理木客

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章