如何計算完全二叉樹的節點數

2022-07-03 23:48:12 字數 2593 閱讀 6577

222.完全二叉樹的節點個數

-----------

如果讓你數一下一棵普通二叉樹有多少個節點,這很簡單,只要在二叉樹的遍歷框架上加一點**就行了。

但是,如果給你一棵完全二叉樹,讓你計算它的節點個數,你會不會?演算法的時間複雜度是多少?這個演算法的時間複雜度應該是 o(logn*logn),如果你心中的演算法沒有達到高效,那麼本文就是給你寫的。

首先要明確一下兩個關於二叉樹的名詞「完全二叉樹」和「滿二叉樹」。

我們說的完全二叉樹如下圖,每一層都是緊湊靠左排列的:

我們說的滿二叉樹如下圖,是一種特殊的完全二叉樹,每層都是是滿的,像乙個穩定的三角形:

說句題外話,關於這兩個定義,中文語境和英文語境似乎有點區別,我們說的完全二叉樹對應英文 complete binary tree,沒有問題。但是我們說的滿二叉樹對應英文 perfect binary tree,而英文中的 full binary tree 是指一棵二叉樹的所有節點要麼沒有孩子節點,要麼有兩個孩子節點。如下:

以上定義出自 wikipedia,這裡就是順便一提,其實名詞叫什麼都無所謂,重要的是演算法操作。本文就按我們中文的語境,記住「滿二叉樹」和「完全二叉樹」的區別,等會會用到

ps:我認真寫了 100 多篇原創,手把手刷 200 道力扣題目,全部發布在 labuladong的演算法小抄,持續更新。建議收藏,按照我的文章順序刷題,掌握各種演算法套路後投再入題海就如魚得水了。

現在回歸正題,如何求一棵完全二叉樹的節點個數呢?

// 輸入一棵完全二叉樹,返回節點總數

int countnodes(treenode root);

如果是乙個普通二叉樹,顯然只要向下面這樣遍歷一邊即可,時間複雜度 o(n):

public int countnodes(treenode root)
那如果是一棵滿二叉樹,節點總數就和樹的高度呈指數關係:

public int countnodes(treenode root) 

// 節點總數就是 2^h - 1

return (int)math.pow(2, h) - 1;

}

完全二叉樹比普通二叉樹特殊,但又沒有滿二叉樹那麼特殊,計算它的節點總數,可以說是普通二叉樹和完全二叉樹的結合版,先看**:

public int countnodes(treenode root) 

while (r != null)

// 如果左右子樹的高度相同,則是一棵滿二叉樹

if (hl == hr)

// 如果左右高度不同,則按照普通二叉樹的邏輯計算

return 1 + countnodes(root.left) + countnodes(root.right);

}

結合剛才針對滿二叉樹和普通二叉樹的演算法,上面這段**應該不難理解,就是乙個結合版,但是其中降低時間複雜度的技巧是非常微妙的

開頭說了,這個演算法的時間複雜度是 o(logn*logn),這是怎麼算出來的呢?

直覺感覺好像最壞情況下是 o(n*logn) 吧,因為之前的 while 需要 logn 的時間,最後要 o(n) 的時間向左右子樹遞迴:

return 1 + countnodes(root.left) + countnodes(root.right);
關鍵點在於,這兩個遞迴只有乙個會真的遞迴下去,另乙個一定會觸發hl == hr而立即返回,不會遞迴下去

為什麼呢?原因如下:

一棵完全二叉樹的兩棵子樹,至少有一棵是滿二叉樹

看圖就明顯了吧,由於完全二叉樹的性質,其子樹一定有一棵是滿的,所以一定會觸發hl == hr,只消耗 o(logn) 的複雜度而不會繼續遞迴。

綜上,演算法的遞迴深度就是樹的高度 o(logn),每次遞迴所花費的時間就是 while 迴圈,需要 o(logn),所以總體的時間複雜度是 o(logn*logn)。

所以說,「完全二叉樹」這個概念還是有它存在的原因的,不僅適用於陣列實現二叉堆,而且連計算節點總數這種看起來簡單的操作都有高效的演算法實現。

_____________

二叉樹 完全二叉樹的節點數

給定一棵完全二叉樹 最後一層所有節點都在最左側,其餘所有層節點數都為2 h 求其節點數。最簡單的方法就是遍歷一遍,把節點數加起來,但時間複雜度太高。以最左邊的路徑長作為二叉樹的高度,對於乙個節點,如果左子樹高度和右子樹高度一樣,說明左子樹為滿二叉樹,此時把其左子樹的節點數計算出來,加入總數,對右子樹...

完全二叉樹求節點數

如上所示,由正整數1,2,3 組成了一顆特殊二叉樹。我們已知這個二叉樹的最後乙個結點是n。現在的問題是,結點m所在的子樹中一共包括多少個結點。比如,n 12,m 3那麼上圖中的結點13,14,15以及後面的結點都是不存在的,結點m所在子樹中包括的結點有3,6,7,12,因此結點m的所在子樹中共有4個...

統計完全二叉樹的節點數

可以遍歷整棵樹來求出來,但是不是最優解法。這裡給出的是時間複雜度為o h 2 詳情參看 程式設計師 面試指南 p176。package com.gxu.dawnlab algorithm4 統計完全二叉樹的節點數 author junbin 2019年6月30日 public class compl...