【19】 二叉樹基礎(上):什麼樣的二叉樹適合用數組來存儲?

1. 樹的基本概念

節點:樹中的每個元素稱爲節點
父子關係:相鄰兩節點的連線,稱爲父子關係
根節點:沒有父節點的節點
葉子節點:沒有子節點的節點
父節點:指向子節點的節點
子節點:被父節點指向的節點
兄弟節點:具有相同父節點的多個節點稱爲兄弟節點關係
節點的高度:節點到葉子節點的最長路徑所包含的邊數,即從下往上數。
節點的深度:根節點到節點的路徑所包含的邊數,即從上往下數。
節點的層數:節點的深度+1(根節點的層數是1)。
樹的高度:等於根節點的高度。

2. 二叉樹的定義

每個節點最多隻有2個子節點的樹,這兩個節點分別是左子節點和右子節點。

3. 二叉樹的分類

  1. 滿二叉樹
    除了葉子節點外,每個節點都有左右兩個子節點,這種二叉樹叫做滿二叉樹。
  2. 完全二叉樹
    葉子節點都在最底下兩層,最後一層葉子節都靠左排列,並且除了最後一層,其他層的節點個數都要達到最大,這種二叉樹叫做完全二叉樹。
  3. 其他二叉樹

4. 二叉樹的存儲(或者表示)

  1. 鏈式存儲
    用鏈表來存儲,每個節點由3個字段,其中一個存儲數據,另外兩個是指向左右子節點的指針。我們只要拎住根節點,就可以通過左右子節點的指針,把整棵樹都串起來。這種存儲方式比較常用,大部分二叉樹代碼都是通過這種方式實現的。
  2. 順序存儲
    用數組來存儲,對於完全二叉樹,如果節點X存儲在數組中的下標爲i,那麼它的左子節點的存儲下標爲2i,右子節點的下標爲2i+1,反過來,下標i/2位置存儲的就是該節點的父節點。注意,根節點存儲在下標爲1的位置。完全二叉樹用數組來存儲時最省內存的方式。

5. 二叉樹的遍歷

  1. 前序遍歷:對於樹中的任意節點來說,先打印這個節點,然後再打印它的左子樹,最後打印它的右子樹。
  2. 中序遍歷:對於樹中的任意節點來說,先打印它的左子樹,然後再打印它的本身,最後打印它的右子樹。
  3. 後序遍歷:對於樹中的任意節點來說,先打印它的左子樹,然後再打印它的右子樹,最後打印它本身。
    前序遍歷的遞推公式:
    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. 思考

  1. 二叉樹有哪幾種存儲方式?什麼樣的二叉樹適合用數組來存儲?
    答:二叉樹既可以用鏈式存儲,也可以用數組順序存儲。數組順序存儲的方式比較適合完全二叉樹,其他類型的二叉樹用數組存儲會比較浪費存儲空間。除此之外,二叉樹裏非常重要的操作就是前、中、後序遍歷操作,遍歷的時間複雜度是 O(n)。
  2. 給定一組數據,比如1,3,5,6,9,10。你來算算,可以構建出多少種不同的二叉樹?
    既然是數組了,說明是完全二叉樹,應該有n的階乘個組合。
  3. 我們講了三種二叉樹的遍歷方式,前、中、後序。實際上,還有另一種遍歷方式,也就是按層遍歷,你知道如何實現嗎?
    二叉樹按層遍歷,可以看作以根結點爲起點,圖的廣度優先遍歷的問題。

7. 參考資料

  1. 王爭老師在極客時間的專欄《數據結構與算法之美》
  2. 專欄下的所有評論

8. 聲明

本文章是學習王爭老師在極客時間專欄——《數據結構與算法之美》的學習總結,文章很多內容直接引用了專欄下的回覆,推薦大家購買王爭老師的專欄進行更加詳細的學習。本文僅供學習使用,勿作他用,如侵犯權益,請聯繫我,立即刪除。

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