演算法系列之二叉樹

2021-10-07 20:17:27 字數 3819 閱讀 2090

資料結構中有一種結構是樹,不過一般我們常見的是樹中的一種特殊型別——二叉樹。二叉樹簡單來說就是每個節點最多有兩個子節點。

如果每個節點都有兩個子節點,那麼我們稱這種二叉樹為滿二叉樹

還有一種二叉樹,其葉子節點都在最底下兩層,最後一層葉子節點都靠左排列,並且除了最後一層,其他層的葉子節點都要達到最大,這種二叉樹叫作完全二叉樹

除了上面那些,這裡還需要特別提到一種樹,二叉搜尋樹。二叉搜尋樹要求,在樹中的任意乙個節點,其左子樹中的每個節點的值,都要小於這個節點的值,而右子樹節點的值都大於這個節點的值。

二叉樹的定義我們已經知道了,但是實際程式設計中我們如何去儲存乙個二叉樹呢?主要有兩種方式,鏈式儲存法順序儲存法

這種方式簡單,也非常常見,主要通過指標來連線不同的節點。

這種儲存方法最適合完全二叉樹,它主要使用陣列來進行儲存。

主要分為4種遍歷方式,

前序遍歷:對於樹中的任意節點來說,先列印這個節點,然後再列印它的左子樹,最後列印它的右子樹。

中序遍歷:對於樹中的任意節點來說,先列印它的左子樹,然後再列印它本身,最後列印它的右子樹。

後序遍歷:對於樹中的任意節點來說,先列印它的左子樹,然後再列印它的右子樹,最後列印這個節點本身。

按層遍歷:從第一層開始,從左到右遍歷整棵二叉樹。

注意:前、中、後遍歷都針對根節點來說的。如根節點在前,那就是前序。

溫習一下概念之後,我們需要做的就是實戰。據博主多年的經驗,概念的東西只是簡單的背誦記憶是沒有用的,必須要應用,這樣才能有深刻的理解。話不多說,我們先來一道開胃菜。

給定乙個二叉樹,找出其最大深度。

二叉樹的深度為根節點到最遠葉子節點的最長路徑上的節點數。

說明: 葉子節點是指沒有子節點的節點。

示例:給定二叉樹 [3,9,20,null,null,15,7],

3

/ \9 20

/ \

15 7

返回它的最大深度 3 。

這道題是求二叉樹的最大深度,也就是二叉樹的最大層數。做法很簡單從根結點一直加到葉子節點,然後比較所有的個數,求出最大的。

/**

* definition for a binary tree node.

* function treenode(val)

*//**

* @param root

* @return

*/var

maxdepth

=function

(root)

return

1+ math.

max(

maxdepth

(root.left)

,maxdepth

(root.right))}

;

舉一反三:有了前面的熱身,可能有些人覺得不過癮。接下來,我們一道中等難度的題。

給定乙個二叉樹,它的每個結點都存放乙個 0-9 的數字,每條從根到葉子節點的路徑都代表乙個數字。

例如,從根到葉子節點路徑 1->2->3 代表數字 123。

計算從根到葉子節點生成的所有數字之和。

說明: 葉子節點是指沒有子節點的節點。

示例 1:

輸入: [1,2,3]

1/ \

2 3

輸出: 25

解釋:從根到葉子節點路徑 1->2 代表數字 12.

從根到葉子節點路徑 1->3 代表數字 13.

因此,數字總和 = 12 + 13 = 25.

示例 2:

輸入: [4,9,0,5,1]

4/ \

9 0

/ \5 1

輸出: 1026

解釋:從根到葉子節點路徑 4->9->5 代表數字 495.

從根到葉子節點路徑 4->9->1 代表數字 491.

從根到葉子節點路徑 4->0 代表數字 40.

因此,數字總和 = 495 + 491 + 40 = 1026.

這題咋一看有點複雜,不過不要急。仔細閱讀題目後,我們能找出線索。只要我們把每一條路徑找到,然後把它們的值加起來就行。

/**

* definition for a binary tree node.

* function treenode(val)

*//**

* @param root

* @return

*/var

sumnumbers

=function

(root)

const nums =

dfs(root,

0, nums)

return nums.

reduce

((total, value, index)

=>,0

)};const

dfs=

(root, total, nums)

=>

if(root.left !==

null)if

(root.right !==

null

)}

舉一反三:這道題有個故事,有位開源軟體的大佬 max howell 去 google 面試。在白板上,他沒能寫出這道題,所以被 google 拒絕了。

翻轉一棵二叉樹。

示例:輸入:

4

/ \

2 7

/ \ / \

1 3 6 9

輸出:

4

/ \

7 2

/ \ / \

9 6 3 1

這道題雖然大佬沒能當場寫出來,但這並不能說明大佬的水平差。這道題就是把左右子樹交換,難點在程式設計實現。如果你沒有思路,不妨還是按照我們前面說的,採用遞迴的思想。

/**

* definition for a binary tree node.

* function treenode(val)

*//**

* @param root

* @return

*/var

inverttree

=function

(root)

if(root.left ===

null

)else

if(root.right ===

null

)else

inverttree

(root.left)

inverttree

(root.right)

return root

};

舉一反三:

小蠢魚演算法系列之二叉樹排序

package com.foolfish.tree desc 二叉樹演算法 author foolfish.chen public class binarytree return the nodevalue public int getnodevalue param nodevalue the no...

演算法基礎之二叉樹

本文主要包括樹相關的演算法,二叉樹結點基本結構如下 function treenode x 本文還會繼續更新。function depth proot var depth 0 var currdepth 0 dfs proot return depth function dfs node currd...

二叉樹之 二叉樹深度

二叉樹深度 獲取最大深度 public static int getmaxdepth treenode root 二叉樹寬度 使用佇列,層次遍歷二叉樹。在上一層遍歷完成後,下一層的所有節點已經放到佇列中,此時佇列中的元素個數就是下一層的寬度。以此類推,依次遍歷下一層即可求出二叉樹的最大寬度 獲取最大...