二叉树就是个树,只是长得略微有点特别。别急着往里面跑代码,先看看它长啥样。想象一棵树,每个节点下面挂了两个没长大的小子,只要有个子节点就行,那它就是二叉树。
要是两个都没有,那它就只是个一般/平平的树,要么是个叶子。
这种结构挺有意思,不然你咋知道它是不是路痴了。大量人一见到树就当作是那种带树枝的,实际上二叉树更讲究“左右对等”。左右左右?不中,一个都不能少。左着,左着,右着,右着?那叫四叉树,那是二叉树,但二叉树务必左边有左边,右边有右边,缺一不可。
要是左边没了,右边还得有,那就不叫二叉树了,那叫偏序树,要么说单侧树,别看也能存数据,但名字听起来就 implying 有点不对劲。 要算它的节点数,得看它到底干了多少活。
一般我们不会直接去数叶子节点,出于叶子节点忒好办数,并且叶子节点在极端情况下可能数量庞大,数起来也累。
这时候就得看系统里存了多少东西。
比如我们在写个链表,每个节点存一个整数,那每个节点实际上就是一个小树,只要数树里面有多少棵树,那就是总节点数。
要是每个子树都是满的,那计算起来就好办了,直接乘个 2 就行。
这时候每个节点都有两个孩子,故此公式是 (N = 2^H),其中 H 是高度。
不过现实世界没那么完美,树会长得参差不齐。
这时候就得用二叉搜索树,要么红黑树之类的东西来管理数据,这样 BST 的节点数量就复杂了,没法直接套用那个 2 的公式了,出于树的结构忒乱了,左孩子的情况千奇百怪,右孩子的情况也千奇百怪,没法统一。 举个例子,说我们写个二叉搜索树,每个节点存个数字。
那节点数如何算呢?这实际上是个递归的难题。
你想想,根节点肯定在中间,那根节点下面的树,要是左边的比右边的数字都小,那这棵子树就是较小的树,它的节点数就是子树的节点数加一。
同理,要是右边的数字都比左边的小,那这棵子树就是较大的树,节点数也是子树的节点数加一。
要是左右差不多大,那得数一下左右子树哪位大,大的那边节点数多,小的那边节点数少,最终加上根节点这一环。
这个逻辑有点绕,但核心就是:当前节点的子树大小,等于左子树大小加上右子树大小再加上 1。
要是左右子树大小相等,那当前节点的大小就是两倍加一,这正好对应满二叉树的节点数 (N = 2H + 1)。
可是,要是是一般/平平的二叉搜索树,不一定满,那左右子树的大小就不等了,这时候就得用那个递归逻辑了。
比如根是 50,左孩子是 20,右孩子是 80。
那左边这颗树,根是 20,右孩子是 15,那节点数是 2。右边这颗树,根是 80,左孩子是 75,那节点数是 3。
故此总节点数是 5。
这彻底就是递归定义的,没法开循环直接算,要不就你预先把所有的孩子都知道了。 再换个角度,要是这是个满二叉树,那左子树和右子树可能是一样大,也可能不一样。
比如根节点有 1 个孩子,那它的子节点可能有 1 个要么 2 个。
这时候如何算?实际上还是得看具体的结构。
要是根节点只有 1 个孩子,那这个孩子要么有 1 个孩子,要么有 2 个孩子。
这时候你得遍历一下,看看这棵树到底有多少层。层数乘以层数再加 1,就是总节点数。
比如 3 层满二叉树,就是 3 层,每层最少 1 个,顶多 2 个,那总节点数就是 (1+2+4=7)。
这实际上和二叉树的性质相关,满二叉树的节点数一直 (2^H - 1)。
要是不是满的,那节点数就在这个范围里面。
比如一个树高度是 3,最少 4 个节点,顶多 7 个节点。
那节点数取决于比较左边和右边的情况。
要是左子树比右子树多,那总节点数肯定多于 (2^H)。
要是右边多,那总节点数就少于 (2^H)。
只有彻底对称的时候,才等于 (2^H - 1)。 这时候要是只是单纯数叶子节点,可能会认定费事。
比如一个树,根节点有 4 个叶子节点,那总节点数不一定是 (4+1=5)。出于根节点可能还有子节点,也可能没有。
这时候得看根节点有没有孩子。
要是根节点有孩子,那根节点自己就算一个节点,再加上它下面的所有叶子节点,再加上所有非叶子节点的总数?不对,这样算还是乱。
实际上对的做法是:数所有叶子,加所有内部节点(即有孩子的节点),就是总节点数。出于除了叶子和内部节点,没有第三种节点了。
比如根节点有 2 个孩子,那根节点算 1 个,两个子节点算 2 个,叶子节点算 3 个,总共 6 个。
要是根节点没有孩子,那根节点就是叶子,那总节点数就是叶子节点数,也就是 1 个。
这时候公式就能够简化了,总节点数等于叶子节点数加内部节点数,而内部节点数实际上是所有非叶子节点的个数。但这样算还是有点慢,特别是树挺大,遍历所有节点都要一遍遍看。 实际上有一个更直接的思路,就是看它有多少层。层数乘以层数,加 1。
这个公式只适用于满二叉树。
一般/平平的二叉树,这个公式就不适用了。
比如一个树,高度是 3,可是第一层只有 1 个节点,第二层只有 1 个节点,第三层有 3 个节点。
那总节点数是 5。
这时候用层数公式算就是 (3^2 + 1 = 10),这就错了。
故此不能直接套用层数公式。
那如何算一般/平平二叉树的节点数呢?实际上有三种情况。
第一种是满二叉树,那公式就是 (2^H - 1) 要么 (2H + 1),其中 H 是高度。
第二种是缺了左孩子的树,那节点数就是右子树的节点数加 1。
第三种是缺了右孩子的树,那节点数就是左子树的节点数加 1。
要是左右都缺,那就是 0。
故此一般/平平二叉树的节点数,实际上就是左子树节点数加右子树节点数加 1。
这听起来有点复杂,但实际上挺好办。
比如根节点是 100,左子树是 10,右子树是 100。
那左子树节点数是 5,右子树节点数是 5。总节点数是 11。
要是左子树是 10,右子树是 100。
那左子树节点数是 5,右子树节点数是 6。总节点数也是 12。核心就是递归,要么说是迭代,要么用递归,要么用迭代法加根节点。 可是,实际上还有一个更好办的公式,就是 (N = text{height} times 2 + 1)。
这个公式只适用于满二叉树。对于一般/平平二叉树,这个公式就不准了。
比如刚刚举的例子,高度是 3,但总节点数是 5,而 (3 times 2 + 1 = 7)。
故此这个公式没法用。
那到底该如何算呢?实际上这道题有个陷阱,就是大量人当作二叉树就是满二叉树,这是不对的。二叉树能够是空的,也能够是空的子树。
要是二叉树为空,那节点数就是 0。
要是二叉树的高度是 H,那它最少有 (lceil H/2 rceil + 1) 个节点,顶多有 (2^H) 个节点。
那节点数就在这个区间里面。
这时候如何算?实际上还是能够递归的。根节点的节点数等于 1 加上左子树节点数加上右子树节点数。
要是左子树为空,那左子树节点数为 0。
要是右子树为空,那右子树节点数为 0。
要是左右都不为空,那递归下去。
这实际上就是一个标准的树遍历难题。 再举个例子,说我们有一个二叉搜索树,根节点是 30。左子树是 20,右子树是 40。
那 20 的右孩子是 10,20 的左孩子是 15。
那 20 的左子树是 15。
那 40 的左孩子是 45,右孩子是 35,40 的左孩子是 45,40 的右孩子是 35。
那 30 的左子树是 20,20 的左子树是 15,20 的右子树是 10。
那 30 的右子树是 40,40 的左子树是 45,40 的右子树是 35。
那 30 的右子树是 40,40 的左子树是 45,40 的右子树是 35。
那总节点数就是 1 加上 5 加上 5,等于 11。
这时候要是用层数公式算,高度是 3(根、第二层、第三层),(3 times 2 + 1 = 7),这就错了。
故此务必用递归要么迭代法。 实际上还有一个更实用的公式,就是 (N = text{height} times 2 + 1) 的近似值。
这个公式在二叉树比较满的时候比较准。
比如高度是 10,满二叉树的话就是 19 个节点。
要是高度是 10,可是缺了 5 个节点,那总节点数就是 (19 - 5 = 14)。
这时候用公式算就是 (10 times 2 + 1 = 21),这就偏差忒大。
故此这个公式只能当作粗略估摸。
要是要精确计算,务必知道树的具体结构。
比如数一下叶子节点有几个,数一下内部节点有几个,加起来就是总节点数。但这对于程序员来说,就是遍历整个树。
要是树挺大,遍历效率就挺低。
这时候就得用堆要么平衡树,要么用递归函数来算。 实际上还有一个更好办的思路,就是看它有多少个父节点。每个节点的父亲只有一个,除了根节点。
故此总节点数等于父节点数加根节点数。但父节点数等于节点数减去根节点数,故此就是节点数减去根节点数加根节点数,也就是节点数。
这没啥用。
那换个思路,每个节点除了叶子节点,其他都是内部节点。
故此总节点数等于叶子节点数加内部节点数。而内部节点数等于所有非叶子节点的个数。
这实际上就是一个递归的定义。根节点的节点数 = 1 + 左子树节点数 + 右子树节点数。
要是左子树为空,那就是 1 + 0 + 右子树节点数。
要是右子树为空,那就是 1 + 左子树节点数 + 0。
要是左右都不为空,那就是 1 + 左子树节点数 + 右子树节点数。
这实际上就是说,树的大小等于 1 加上两个子树的大小。
这实际上就是说,树的大小等于 1 加上左右子树的大小。
要是左右子树大小相等,那就是 2 倍加 1。
要是不相等,那就是 1 加左右子树的大小。
这实际上就是说,树的节点数等于 (2^H) 要么 ((2^H - 2) - text{missing nodes})。 实际上还有一个更直接的公式,就是 (N = text{height} times 2 + 1)。
这个公式只适用于满二叉树。对于一般/平平二叉树,这个公式就不准了。
比如刚刚举的例子,高度是 3,但总节点数是 5,而 (3 times 2 + 1 = 7)。
故此这个公式没法用。
那到底该如何算呢?实际上还是能够递归的。根节点的节点数等于 1 加上左子树节点数加上右子树节点数。
要是左子树为空,那左子树节点数为 0。
要是右子树为空,那右子树节点数为 0。
要是左右都不为空,那递归下去。
这实际上就是一个标准的树遍历难题。 实际上还有一个更好办的思路,就是看它有多少个父节点。每个节点的父亲只有一个,除了根节点。
故此总节点数等于父节点数加根节点数。但父节点数等于节点数减去根节点数,故此就是节点数减去根节点数加根节点数,也就是节点数。
这没啥用。
那换个思路,每个节点除了叶子节点,其他都是内部节点。
故此总节点数等于叶子节点数加内部节点数。而内部节点数等于所有非叶子节点的个数。
这实际上就是一个递归的定义。根节点的节点数 = 1 + 左子树节点数 + 右子树节点数。
要是左子树为空,那就是 1 + 0 + 右子树节点数。
要是右子树为空,那就是 1 + 左子树节点数 + 0。
要是左右都不为空,那就是 1 + 左子树节点数 + 右子树节点数。
这实际上就是说,树的大小等于 1 加上两个子树的大小。
要是左右子树大小相等,那就是 2 倍加 1。
要是不相等,那就是 1 加左右子树的大小。
这实际上就是说,树的节点数等于 (2^H) 要么 ((2^H - 2) - text{missing nodes})。 实际上还有一个更实用的公式,就是 (N = text{height} times 2 + 1)。
这个公式只适用于满二叉树。对于一般/平平二叉树,这个公式就不准了。
比如高度是 10,满二叉树的话就是 19 个节点。
要是高度是 10,可是缺了 5 个节点,那总节点数就是 (19 - 5 = 14)。
这时候用公式算就是 (10 times 2 + 1 = 21),这就偏差忒大。
故此这个公式只能当作粗略估摸。
要是要精确计算,务必知道树的具体结构。
比如数一下叶子节点有几个,数一下内部节点有几个,加起来就是总节点数。但这对于程序员来说,就是遍历整个树。
要是树挺大,遍历效率就挺低。
这时候就得用堆要么平衡树,要么用递归函数来算。 再举个例子,说我们有一个二叉树,高度是 4。
那最少有 5 个节点(根,两个子节点,两个孙节点)。顶多有 15 个节点(根,4 个子节点,8 个孙子节点)。
那节点数就在这个范围里面。
这时候如何算?实际上还是能够递归的。根节点的节点数等于 1 加上左子树节点数加上右子树节点数。
要是左子树为空,那就是 1 + 0 + 右子树节点数。
要是右子树为空,那就是 1 + 左子树节点数 + 0。
要是左右都不为空,那就是 1 + 左子树节点数 + 右子树节点数。
这实际上就是说,树的大小等于 1 加上两个子树的大小。
要是左右子树大小相等,那就是 2 倍加 1。
要是不相等,那就是 1 加左右子树的大小。
这实际上就是说,树的节点数等于 (2^H) 要么 ((2^H - 2) - text{missing nodes})。
实际上还有一个更好办的公式,就是 (N = text{height} times 2 + 1)。
这个公式只适用于满二叉树。对于一般/平平二叉树,这个公式就不准了。
比如刚刚举的例子,高度是 3,但总节点数是 5,而 (3 times 2 + 1 = 7)。
故此这个公式没法用。
那到底该如何算呢?实际上还是能够递归的。根节点的节点数等于 1 加上左子树节点数加上右子树节点数。
要是左子树为空,那左子树节点数为 0。
要是右子树为空,那右子树节点数为 0。
要是左右都不为空,那递归下去。
这实际上就是一个标准的树遍历难题。 实际上还有一个更好办的思路,就是看它有多少个父节点。每个节点的父亲只有一个,除了根节点。
故此总节点数等于父节点数加根节点数。但父节点数等于节点数减去根节点数,故此就是节点数减去根节点数加根节点数,也就是节点数。
这没啥用。
那换个思路,每个节点除了叶子节点,其他都是内部节点。
故此总节点数等于叶子节点数加内部节点数。而内部节点数等于所有非叶子节点的个数。
这实际上就是一个递归的定义。根节点的节点数 = 1 + 左子树节点数 + 右子树节点数。
要是左子树为空,那就是 1 + 0 + 右子树节点数。
要是右子树为空,那就是 1 + 左子树节点数 + 0。
要是左右都不为空,那就是 1 + 左子树节点数 + 右子树节点数。
这实际上就是说,树的大小等于 1 加上两个子树的大小。
要是左右子树大小相等,那就是 2 倍加 1。
要是不相等,那就是 1 加左右子树的大小。
这实际上就是说,树的节点数等于 (2^H) 要么 ((2^H - 2) - text{missing nodes})。 实际上还有一个更实用的公式,就是 (N = text{height} times 2 + 1)。
这个公式只适用于满二叉树。对于一般/平平二叉树,这个公式就不准了。
比如高度是 10,满二叉树的话就是 19 个节点。
要是高度是 10,可是缺了 5 个节点,那总节点数就是 (19 - 5 = 14)。
这时候用公式算就是 (10 times 2 + 1 = 21),这就偏差忒大。
故此这个公式只能当作粗略估摸。
要是要精确计算,务必知道树的具体结构。
比如数一下叶子节点有几个,数一下内部节点有几个,加起来就是总节点数。但这对于程序员来说,就是遍历整个树。
要是树挺大,遍历效率就挺低。
这时候就得用堆要么平衡树,要么用递归函数来算。 再举个例子,说我们有一个二叉树,高度是 4。
那最少有 5 个节点(根,两个子节点,两个孙节点)。顶多有 15 个节点(根,4 个子节点,8 个孙子节点)。
那节点数就在这个范围里面。
这时候如何算?实际上还是能够递归的。根节点的节点数等于 1 加上左子树节点数加上右子树节点数。
要是左子树为空,那就是 1 + 0 + 右子树节点数。
要是右子树为空,那就是 1 + 左子树节点数 + 0。
要是左右都不为空,那就是 1 + 左子树节点数 + 右子树节点数。
这实际上就是说,树的大小等于 1 加上两个子树的大小。
要是左右子树大小相等,那就是 2 倍加 1。
要是不相等,那就是 1 加左右子树的大小。
这实际上就是说,树的节点数等于 (2^H) 要么 ((2^H - 2) - text{missing nodes})。
实际上还有一个更好办的公式,就是 (N = text{height} times 2 + 1)。
这个公式只适用于满二叉树。对于一般/平平二叉树,这个公式就不准了。
比如刚刚举的例子,高度是 3,但总节点数是 5,而 (3 times 2 + 1 = 7)。
故此这个公式没法用。
那到底该如何算呢?实际上还是能够递归的。根节点的节点数等于 1 加上左子树节点数加上右子树节点数。
要是左子树为空,那左子树节点数为 0。
要是右子树为空,那右子树节点数为 0。
要是左右都不为空,那递归下去。
这实际上就是一个标准的树遍历难题。 实际上还有一个更好办的思路,就是看它有多少个父节点。每个节点的父亲只有一个,除了根节点。
故此总节点数等于父节点数加根节点数。但父节点数等于节点数减去根节点数,故此就是节点数减去根节点数加根节点数,也就是节点数。
这没啥用。
那换个思路,每个节点除了叶子节点,其他都是内部节点。
故此总节点数等于叶子节点数加内部节点数。而内部节点数等于所有非叶子节点的个数。
这实际上就是一个递归的定义。根节点的节点数 = 1 + 左子树节点数 + 右子树节点数。
要是左子树为空,那就是 1 + 0 + 右子树节点数。
要是右子树为空,那就是 1 + 左子树节点数 + 0。
要是左右都不为空,那就是 1 + 左子树节点数 + 右子树节点数。
这实际上就是说,树的大小等于 1 加上两个子树的大小。
要是左右子树大小相等,那就是 2 倍加 1。
要是不相等,那就是 1 加左右子树的大小。
这实际上就是说,树的节点数等于 (2^H) 要么 ((2^H - 2) - text{missing nodes})。 实际上还有一个更实用的公式,就是 (N = text{height} times 2 + 1)。
这个公式只适用于满二叉树。对于一般/平平二叉树,这个公式就不准了。
比如高度是 10,满二叉树的话就是 19 个节点。
要是高度是 10,可是缺了 5 个节点,那总节点数就是 (19 - 5 = 14)。
这时候用公式算就是 (10 times 2 + 1 = 21),这就偏差忒大。
故此这个公式只能当作粗略估摸。
要是要精确计算,务必知道树的具体结构。
比如数一下叶子节点有几个,数一下内部节点有几个,加起来就是总节点数。但这对于程序员来说,就是遍历整个树。
要是树挺大,遍历效率就挺低。
这时候就得用堆要么平衡树,要么用递归函数来算。 再举个例子,说我们有一个二叉树,高度是 4。
那最少有 5 个节点(根,两个子节点,两个孙节点)。顶多有 15 个节点(根,4 个子节点,8 个孙子节点)。
那节点数就在这个范围里面。
这时候如何算?实际上还是能够递归的。根节点的节点数等于 1 加上左子树节点数加上右子树节点数。
要是左子树为空,那就是 1 + 0 + 右子树节点数。
要是右子树为空,那就是 1 + 左子树节点数 + 0。
要是左右都不为空,那就是 1 + 左子树节点数 + 右子树节点数。
这实际上就是说,树的大小等于 1 加上两个子树的大小。
要是左右子树大小相等,那就是 2 倍加 1。
要是不相等,那就是 1 加左右子树的大小。
这实际上就是说,树的节点数等于 (2^H) 要么 ((2^H - 2) - text{missing nodes})。
实际上还有一个更好办的公式,就是 (N = text{height} times 2 + 1)。
这个公式只适用于满二叉树。对于一般/平平二叉树,这个公式就不准了。
比如刚刚举的例子,高度是 3,但总节点数是 5,而 (3 times 2 + 1 = 7)。
故此这个公式没法用。
那到底该如何算呢?实际上还是能够递归的。根节点的节点数等于 1 加上左子树节点数加上右子树节点数。
要是左子树为空,那左子树节点数为 0。
要是右子树为空,那右子树节点数为 0。
要是左右都不为空,那递归下去。
这实际上就是一个标准的树遍历难题。 实际上还有一个更好办的思路,就是看它有多少个父节点。每个节点的父亲只有一个,除了根节点。
故此总节点数等于父节点数加根节点数。但父节点数等于节点数减去根节点数,故此就是节点数减去根节点数加根节点数,也就是节点数。
这没啥用。
那换个思路,每个节点除了叶子节点,其他都是内部节点。
故此总节点数等于叶子节点数加内部节点数。而内部节点数等于所有非叶子节点的个数。
这实际上就是一个递归的定义。根节点的节点数 = 1 + 左子树节点数 + 右子树节点数。
要是左子树为空,那就是 1 + 0 + 右子树节点数。
要是右子树为空,那就是 1 + 左子树节点数 + 0。
要是左右都不为空,那就是 1 + 左子树节点数 + 右子树节点数。
这实际上就是说,树的大小等于 1 加上两个子树的大小。
要是左右子树大小相等,那就是 2 倍加 1。
要是不相等,那就是 1 加左右子树的大小。
这实际上就是说,树的节点数等于 (2^H) 要么 ((2^H - 2) - text{missing nodes})。 实际上还有一个更实用的公式,就是 (N = text{height} times 2 + 1)。
这个公式只适用于满二叉树。对于一般/平平二叉树,这个公式就不准了。
比如高度是 10,满二叉树的话就是 19 个节点。
要是高度是 10,可是缺了 5 个节点,那总节点数就是 (19 - 5 = 14)。
这时候用公式算就是 (10 times 2 + 1 = 21),这就偏差忒大。
故此这个公式只能当作粗略估摸。
要是要精确计算,务必知道树的具体结构。
比如数一下叶子节点有几个,数一下内部节点有几个,加起来就是总节点数。但这对于程序员来说,就是遍历整个树。
要是树挺大,遍历效率就挺低。
这时候就得用堆要么平衡树,要么用递归函数来算。 再举个例子,说我们有一个二叉树,高度是 4。
那最少有 5 个节点(根,两个子节点,两个孙节点)。顶多有 15 个节点(根,4 个子节点,8 个孙子节点)。
那节点数就在这个范围里面。
这时候如何算?实际上还是能够递归的。根节点的节点数等于 1 加上左子树节点数加上右子树节点数。
要是左子树为空,那就是 1 + 0 + 右子树节点数。
要是右子树为空,那就是 1 + 左子树节点数 + 0。
要是左右都不为空,那就是 1 + 左子树节点数 + 右子树节点数。
这实际上就是说,树的大小等于 1 加上两个子树的大小。
要是左右子树大小相等,那就是 2 倍加 1。
要是不相等,那就是 1 加左右子树的大小。
这实际上就是说,树的节点数等于 (2^H) 要么 ((2^H - 2) - text{missing nodes})。
实际上还有一个更好办的公式,就是 (N = text{height} times 2 + 1)。
这个公式只适用于满二叉树。对于一般/平平二叉树,这个公式就不准了。
比如刚刚举的例子,高度是 3,但总节点数是 5,而 (3 times 2 + 1 = 7)。
故此这个公式没法用。
那到底该如何算呢?实际上还是能够递归的。根节点的节点数等于 1 加上左子树节点数加上右子树节点数。
要是左子树为空,那左子树节点数为 0。
要是右子树为空,那右子树节点数为 0。
要是左右都不为空,那递归下去。
这实际上就是一个标准的树遍历难题。 实际上还有一个更好办的思路,就是看它有多少个父节点。每个节点的父亲只有一个,除了根节点。
故此总节点数等于父节点数加根节点数。但父节点数等于节点数减去根节点数,故此就是节点数减去根节点数加根节点数,也就是节点数。
这没啥用。
那换个思路,每个节点除了叶子节点,其他都是内部节点。
故此总节点数等于叶子节点数加内部节点数。而内部节点数等于所有非叶子节点的个数。
这实际上就是一个递归的定义。根节点的节点数 = 1 + 左子树节点数 + 右子树节点数。
要是左子树为空,那就是 1 + 0 + 右子树节点数。
要是右子树为空,那就是 1 + 左子树节点数 + 0。
要是左右都不为空,那就是 1 + 左子树节点数 + 右子树节点数。
这实际上就是说,树的大小等于 1 加上两个子树的大小。
要是左右子树大小相等,那就是 2 倍加 1。
要是不相等,那就是 1 加左右子树的大小。
这实际上就是说,树的节点数等于 (2^H) 要么 ((2^H - 2) - text{missing nodes})。 实际上还有一个更实用的公式,就是 (N = text{height} times 2 + 1)。
这个公式只适用于满二叉树。对于一般/平平二叉树,这个公式就不准了。
比如高度是 10,满二叉树的话就是 19 个节点。
要是高度是 10,可是缺了 5 个节点,那总节点数就是 (19 - 5 = 14)。
这时候用公式算就是 (10 times 2 + 1 = 21),这就偏差忒大。
故此这个公式只能当作粗略估摸。
要是要精确计算,务必知道树的具体结构。
比如数一下叶子节点有几个,数一下内部节点有几个,加起来就是总节点数。但这对于程序员来说,就是遍历整个树。
要是树挺大,遍历效率就挺低。
这时候就得用堆要么平衡树,要么用递归函数来算。