1. 樹的基本概念
節點:樹中的每個元素稱爲節點
父子關係:相鄰兩節點的連線,稱爲父子關係
根節點:沒有父節點的節點
葉子節點:沒有子節點的節點
父節點:指向子節點的節點
子節點:被父節點指向的節點
兄弟節點:具有相同父節點的多個節點稱爲兄弟節點關係
節點的高度:節點到葉子節點的最長路徑所包含的邊數,即從下往上數。
節點的深度:根節點到節點的路徑所包含的邊數,即從上往下數。
節點的層數:節點的深度+1(根節點的層數是1)。
樹的高度:等於根節點的高度。
2. 二叉樹的定義
每個節點最多隻有2個子節點的樹,這兩個節點分別是左子節點和右子節點。
3. 二叉樹的分類
- 滿二叉樹
除了葉子節點外,每個節點都有左右兩個子節點,這種二叉樹叫做滿二叉樹。 - 完全二叉樹
葉子節點都在最底下兩層,最後一層葉子節都靠左排列,並且除了最後一層,其他層的節點個數都要達到最大,這種二叉樹叫做完全二叉樹。 - 其他二叉樹
4. 二叉樹的存儲(或者表示)
- 鏈式存儲
用鏈表來存儲,每個節點由3個字段,其中一個存儲數據,另外兩個是指向左右子節點的指針。我們只要拎住根節點,就可以通過左右子節點的指針,把整棵樹都串起來。這種存儲方式比較常用,大部分二叉樹代碼都是通過這種方式實現的。 - 順序存儲
用數組來存儲,對於完全二叉樹,如果節點X存儲在數組中的下標爲i,那麼它的左子節點的存儲下標爲2i,右子節點的下標爲2i+1,反過來,下標i/2位置存儲的就是該節點的父節點。注意,根節點存儲在下標爲1的位置。完全二叉樹用數組來存儲時最省內存的方式。
5. 二叉樹的遍歷
- 前序遍歷:對於樹中的任意節點來說,先打印這個節點,然後再打印它的左子樹,最後打印它的右子樹。
- 中序遍歷:對於樹中的任意節點來說,先打印它的左子樹,然後再打印它的本身,最後打印它的右子樹。
- 後序遍歷:對於樹中的任意節點來說,先打印它的左子樹,然後再打印它的右子樹,最後打印它本身。
前序遍歷的遞推公式:
preOrder® = print r->preOrder(r->left)->preOrder(r->right)
中序遍歷的遞推公式:
inOrder® = inOrder(r->left)->print r->inOrder(r->right)
後序遍歷的遞推公式:
postOrder® = postOrder(r->left)->postOrder(r->right)->print r
時間複雜度:3種遍歷方式中,每個節點最多會被訪問2次,所以時間複雜度是O(n)。
6. 思考
- 二叉樹有哪幾種存儲方式?什麼樣的二叉樹適合用數組來存儲?
答:二叉樹既可以用鏈式存儲,也可以用數組順序存儲。數組順序存儲的方式比較適合完全二叉樹,其他類型的二叉樹用數組存儲會比較浪費存儲空間。除此之外,二叉樹裏非常重要的操作就是前、中、後序遍歷操作,遍歷的時間複雜度是 O(n)。 - 給定一組數據,比如1,3,5,6,9,10。你來算算,可以構建出多少種不同的二叉樹?
既然是數組了,說明是完全二叉樹,應該有n的階乘個組合。 - 我們講了三種二叉樹的遍歷方式,前、中、後序。實際上,還有另一種遍歷方式,也就是按層遍歷,你知道如何實現嗎?
二叉樹按層遍歷,可以看作以根結點爲起點,圖的廣度優先遍歷的問題。
7. 參考資料
- 王爭老師在極客時間的專欄《數據結構與算法之美》
- 專欄下的所有評論
8. 聲明
本文章是學習王爭老師在極客時間專欄——《數據結構與算法之美》的學習總結,文章很多內容直接引用了專欄下的回覆,推薦大家購買王爭老師的專欄進行更加詳細的學習
。本文僅供學習使用,勿作他用,如侵犯權益,請聯繫我,立即刪除。