【數據結構與算法之美】二叉樹基礎(上):什麼樣的二叉樹適合用數組來存儲?

一、樹

1.樹的常用概念
根節點、葉子節點、父節點、子節點、兄弟節點,還有節點的高度、深度以及層數,樹的高度。
2.概念解釋
節點:樹中的每個元素稱爲節點
父子關係:相鄰兩節點的連線,稱爲父子關係
根節點:沒有父節點的節點
葉子節點:沒有子節點的節點
父節點:指向子節點的節點
子節點:被父節點指向的節點
兄弟節點:具有相同父節點的多個節點稱爲兄弟節點關係
節點的高度:節點到葉子節點的最長路徑所包含的邊數
節點的深度:根節點到節點的路徑所包含的邊數
節點的層數:節點的深度+1(根節點的層數是1)
樹的高度:等於根節點的高度

二、二叉樹

1.概念
①什麼是二叉樹?
每個節點最多隻有2個子節點的樹,這兩個節點分別是左子節點和右子節點。
②什麼是滿二叉樹?
有一種二叉樹,除了葉子節點外,每個節點都有左右兩個子節點,這種二叉樹叫做滿二叉樹。
③什麼是完全二叉樹?
葉子節點都在最底下兩層,最後一層的葉子節點都靠左排列,並且除了最後一層,其他層的節點個數都要達到最大,這種二叉樹叫作完全二叉樹
2.完全二叉樹的存儲
①鏈式存儲
每個節點由3個字段,其中一個存儲數據,另外兩個是指向左右子節點的指針。我們只要拎住根節點,就可以通過左右子節點的指針,把整棵樹都串起來。這種存儲方式比較常用,大部分二叉樹代碼都是通過這種方式實現的。
②順序存儲
用數組來存儲,對於完全二叉樹,如果節點X存儲在數組中的下標爲i,那麼它的左子節點的存儲下標爲2*i,右子節點的下標爲2*i+1,反過來,下標i/2位置存儲的就是該節點的父節點。注意,根節點存儲在下標爲1的位置。完全二叉樹用數組來存儲時最省內存的方式。
3.二叉樹的遍歷
①前序遍歷:對於樹中的任意節點來說,先打印這個節點,然後再打印它的左子樹,最後打印它的右子樹。
②中序遍歷:對於樹中的任意節點來說,先打印它的左子樹,然後再打印它的本身,最後打印它的右子樹。
③後序遍歷:對於樹中的任意節點來說,先打印它的左子樹,然後再打印它的右子樹,最後打印它本身。
前序遍歷的遞推公式:
preOrder(r) = print r->preOrder(r->left)->preOrder(r->right)
中序遍歷的遞推公式:
inOrder(r) = inOrder(r->left)->print r->inOrder(r->right)
後序遍歷的遞推公式:
postOrder(r) = postOrder(r->left)->postOrder(r->right)->print r
時間複雜度:3種遍歷方式中,每個節點最多會被訪問2次,所以時間複雜度是O(n)。

三、課後思考

1.二叉樹有哪幾種存儲方式?什麼樣的二叉樹適合用數組來存儲?

1)兩種方法,一種是基於指針或者引用的二叉鏈式存儲法,一種是基於數組的順序存儲法。

2)完全二叉樹,那用數組存儲無疑是最節省內存的一種方式。因爲數組的存儲方式並不需要像鏈式存儲法那樣,要存儲額外的左右子節點的指針。這也是爲什麼完全二叉樹會單獨拎出來的原因,也是爲什麼完全二叉樹要求最後一層的子節點都靠左的原因。

3)堆其實就是一種完全二叉樹,最常用的存儲方式就是數組。


2.給定一組數據,比如1,3,5,6,9,10.你來算算,可以構建出多少種不同的二叉樹?【卡塔蘭數】

推算法:當只有1個數的時候,能構建1個二叉樹;2個數時是2個二叉樹;3個數有6個二叉樹;再看下4個數,原來是24個;最後得出n!

3.我們講了三種二叉樹的遍歷方式,前、中、後序。實際上,還有另一種遍歷方式,也就是按層遍歷,你知道如何實現嗎?

二叉樹按層遍歷,可以看作以根結點爲起點,圖的廣度優先遍歷的問題。

leetcode上有個類似的題目,鏈接爲:https://leetcode.com/problems/binary-tree-level-order-traversal/

 

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