資料結構中有一種結構是樹,不過一般我們常見的是樹中的一種特殊型別——二叉樹。二叉樹簡單來說就是每個節點最多有兩個子節點。
如果每個節點都有兩個子節點,那麼我們稱這種二叉樹為滿二叉樹。
還有一種二叉樹,其葉子節點都在最底下兩層,最後一層葉子節點都靠左排列,並且除了最後一層,其他層的葉子節點都要達到最大,這種二叉樹叫作完全二叉樹。
除了上面那些,這裡還需要特別提到一種樹,二叉搜尋樹。二叉搜尋樹要求,在樹中的任意乙個節點,其左子樹中的每個節點的值,都要小於這個節點的值,而右子樹節點的值都大於這個節點的值。
二叉樹的定義我們已經知道了,但是實際程式設計中我們如何去儲存乙個二叉樹呢?主要有兩種方式,鏈式儲存法和順序儲存法。
這種方式簡單,也非常常見,主要通過指標來連線不同的節點。
這種儲存方法最適合完全二叉樹,它主要使用陣列來進行儲存。
主要分為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 二叉樹寬度 使用佇列,層次遍歷二叉樹。在上一層遍歷完成後,下一層的所有節點已經放到佇列中,此時佇列中的元素個數就是下一層的寬度。以此類推,依次遍歷下一層即可求出二叉樹的最大寬度 獲取最大...