自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

淺析二叉樹(shù)的層次遍歷和最大深度

開(kāi)發(fā) 前端
在講解二叉樹(shù)的時(shí)候,提到二叉樹(shù)的遍歷除了前中后序遍歷,還有層次遍歷。前中后序這三種遍歷方法以及可以通過(guò)遞歸的方式實(shí)現(xiàn)了,那么今天就來(lái)講講層次遍歷吧!

 [[375572]]

在講解二叉樹(shù)的時(shí)候,提到二叉樹(shù)的遍歷除了前中后序遍歷,還有層次遍歷。

前中后序這三種遍歷方法以及可以通過(guò)遞歸的方式實(shí)現(xiàn)了,那么今天就來(lái)講講層次遍歷吧!

LeetCode 第 102題:二叉樹(shù)的層次遍歷

給你一個(gè)二叉樹(shù),請(qǐng)你返回其按 層序遍歷 得到的節(jié)點(diǎn)值。(即逐層地,從左到右訪問(wèn)所有節(jié)點(diǎn))。

  1. 示例:  
  2. 二叉樹(shù):[3,9,20,null,null,15,7],  
  3. #     3 
  4. #   / \ 
  5. #  9  20 
  6. #    /  \ 
  7. #   15   7 
  8. 返回其層次遍歷結(jié)果:  
  9.  [3], 
  10.  [9,20], 
  11.  [15,7] 

對(duì)于這道二叉樹(shù)題目,我們要遍歷每一層的每一個(gè)節(jié)點(diǎn),可以考慮分別用BFS(廣度優(yōu)先搜索)和DFS(深度優(yōu)先搜索)來(lái)解決,下面先簡(jiǎn)單介紹BFS,后續(xù)文章繼續(xù)深入。

有兩種通用的遍歷樹(shù)的策略:

深度優(yōu)先搜索算法(英語(yǔ):Depth-First-Search,簡(jiǎn)稱DFS)是一種用于遍歷或搜索樹(shù)或圖的算法。沿著樹(shù)的深度遍歷樹(shù)的節(jié)點(diǎn),盡可能深的搜索樹(shù)的分支。當(dāng)節(jié)點(diǎn)的所在邊都己被探尋過(guò),搜索將回溯到發(fā)現(xiàn)節(jié)點(diǎn)的那條邊的起始節(jié)點(diǎn)。

深度優(yōu)先搜索策略又可以根據(jù)根節(jié)點(diǎn)、左孩子和右孩子的相對(duì)順序被細(xì)分為先序遍歷,中序遍歷和后序遍歷。

寬度優(yōu)先搜索算法(又稱廣度優(yōu)先搜索 英語(yǔ):Breadth-First Search, 簡(jiǎn)稱BFS )

我們按照高度順序一層一層的訪問(wèn)整棵樹(shù),高層次的節(jié)點(diǎn)將會(huì)比低層次的節(jié)點(diǎn)先被訪問(wèn)到,最短路徑問(wèn)題常用此算法。

本題就是用廣度優(yōu)先搜索,對(duì)二叉樹(shù)按照層進(jìn)行搜索,搜索邏輯如下圖所示:


根據(jù)我們熟悉的BFS搜索方法,二叉樹(shù)的層次遍歷,關(guān)鍵要用到隊(duì)列,父結(jié)點(diǎn)出,就要判斷子結(jié)點(diǎn)是否為空,非空則馬上進(jìn)入隊(duì)列,類似廣度優(yōu)先queue隊(duì)列。

把每個(gè)沒(méi)有搜索到的點(diǎn)依次放入隊(duì)列,然后再?gòu)棾鲫?duì)列的頭部元素作為當(dāng)前遍歷節(jié)點(diǎn),并進(jìn)行記錄。接下來(lái)對(duì)此節(jié)點(diǎn)的所有相鄰節(jié)點(diǎn)進(jìn)行搜索,將所有有效且未被訪問(wèn)過(guò)的節(jié)點(diǎn)壓入隊(duì)列中。

  1. # Definition for a binary tree node. 
  2. # class TreeNode: 
  3. #     def __init__(self, x): 
  4. #         self.val = x 
  5. #         self.left = None 
  6. #         self.right = None 
  7. from collections import deque 
  8.  
  9. class Solution(object): 
  10.     def levelOrder(self, root): 
  11.         res = [] 
  12.         if root is None: 
  13.             return res 
  14.         q = deque([root]) 
  15.         res.append([root.val]) 
  16.         while q: 
  17.             size = len(q) 
  18.             level = [] 
  19.             for i in range(size): 
  20.                 node = q.popleft() 
  21.                 if node.left != None: 
  22.                     q.append(node.left
  23.                     level.append(node.left.val) 
  24.                 if node.right != None: 
  25.                     q.append(node.right
  26.                     level.append(node.right.val) 
  27.             if level
  28.                 res.append(level
  29.         return res 

LeetCode 第 107題:二叉樹(shù)的層次遍歷II

給定一個(gè)二叉樹(shù),返回其節(jié)點(diǎn)值自底向上的層次遍歷。(即按從葉子節(jié)點(diǎn)所在層到根節(jié)點(diǎn)所在的層,逐層從左向右遍歷)

  1. #給定二叉樹(shù) [3,9,20,null,null,15,7],  
  2. #     3 
  3. #   / \ 
  4. #  9  20 
  5. #    /  \ 
  6. #   15   7 
  7. # 返回其自底向上的層次遍歷為:  
  8. # [ 
  9. #  [15,7], 
  10. #  [9,20], 
  11. #  [3] 
  12. #] 
  13. # Related Topics 樹(shù) 廣度優(yōu)先搜索 

和LeetCode 第 102題:二叉樹(shù)的層次遍歷完全一樣,就是最后的結(jié)果改為return res[::-1]

  1. class Solution: 
  2.     def levelOrderBottom(self, root: TreeNode) -> List[List[int]]: 
  3.         res = [] 
  4.         if root is None: 
  5.             return res 
  6.         q = deque([root]) 
  7.         res.append([root.val]) 
  8.         while q: 
  9.             size = len(q) 
  10.             level = [] 
  11.             for i in range(size): 
  12.                 node = q.popleft() 
  13.                 if node.left != None: 
  14.                     q.append(node.left
  15.                     level.append(node.left.val) 
  16.                 if node.right != None: 
  17.                     q.append(node.right
  18.                     level.append(node.right.val) 
  19.             if level
  20.                 res.append(level
  21.         return res[::-1] 

LeetCode 第 104題:二叉樹(shù)的最大深度

給定一個(gè)二叉樹(shù),找出其最大深度。

  1. # 二叉樹(shù)的深度為根節(jié)點(diǎn)到最遠(yuǎn)葉子節(jié)點(diǎn)的最長(zhǎng)路徑上的節(jié)點(diǎn)數(shù)。  
  2. # 說(shuō)明: 葉子節(jié)點(diǎn)是指沒(méi)有子節(jié)點(diǎn)的節(jié)點(diǎn)。  
  3. # 示例:  
  4. #給定二叉樹(shù) [3,9,20,null,null,15,7],  
  5. #     3 
  6. #   / \ 
  7. #  9  20 
  8. #    /  \ 
  9. #   15   7  
  10. # 返回它的最大深度 3 。  
  11. # Related Topics 樹(shù) 深度優(yōu)先搜索 

看到該題目,首先想到的是使用遞歸來(lái)實(shí)現(xiàn),遞歸的基本條件是訪問(wèn)到根節(jié)點(diǎn)(左右子樹(shù)為空);遞歸條件是訪問(wèn)左子樹(shù)或右子樹(shù);中間處理邏輯是將子樹(shù)深度+1,即為最終深度。

  1. # class TreeNode: 
  2. #     def __init__(self, x): 
  3. #         self.val = x 
  4. #         self.left = None 
  5. #         self.right = None 
  6.  
  7. class Solution: 
  8.  # 簡(jiǎn)化的遞歸 
  9.  def maxDepth(self, root: TreeNode) -> int
  10.         if not root: 
  11.             return 0 
  12.         return max(self.maxDepth(root.left), self.maxDepth(root.right))+1 
  13.  def maxDepth(self, root: TreeNode) -> int:   
  14.   if not root: return 0  
  15.   # 分別得到左右子樹(shù)的最大深度 
  16.   left = self.maxDepth(root.left)     
  17.   right = self.maxDepth(root.right)     
  18.   return max(leftright) +1 

LeetCode 第 110題:平衡二叉樹(shù)

給定一個(gè)二叉樹(shù),判斷它是否是高度平衡的二叉樹(shù)。

  1. # 本題中,一棵高度平衡二叉樹(shù)定義為:  
  2. # 一個(gè)二叉樹(shù)每個(gè)節(jié)點(diǎn) 的左右兩個(gè)子樹(shù)的高度差的絕對(duì)值不超過(guò)1。  
  3. # 示例 1:  
  4. # 給定二叉樹(shù) [3,9,20,null,null,15,7]  
  5. #     3 
  6. #   / \ 
  7. #  9  20 
  8. #    /  \ 
  9. #   15   7  
  10. # 返回 true 。  
  11. #示例 2:  
  12. # 給定二叉樹(shù) [1,2,2,3,3,null,null,4,4]  
  13. #        1 
  14. #      / \ 
  15. #     2   2 
  16. #    / \ 
  17. #   3   3 
  18. #  / \ 
  19. # 4   4 
  20. # 返回 false 。  
  21. # Related Topics 樹(shù) 深度優(yōu)先搜索 

定義一個(gè)獲取當(dāng)前節(jié)點(diǎn)高度的方法, 可以參考上面:求二叉樹(shù)的最大深度

左右兩個(gè)子樹(shù)的高度差的絕對(duì)值超過(guò)1,則為false

如果當(dāng)前節(jié)點(diǎn)的左右子樹(shù)滿足高度差的絕對(duì)值不超過(guò)1,則需要繼續(xù)判斷其左右子樹(shù)分別是否是平衡二叉樹(shù)。

對(duì)于每個(gè)節(jié)點(diǎn),左子樹(shù)和右子樹(shù)都是平衡樹(shù),并且得到左子樹(shù)和右子樹(shù)的高度,只要高度差小于1,則為true。

  1. # Definition for a binary tree node. 
  2. # class TreeNode(object): 
  3. #     def __init__(self, x): 
  4. #         self.val = x 
  5. #         self.left = None 
  6. #         self.right = None 
  7.  
  8. class Solution: 
  9.     def isBalanced(self, root: TreeNode) -> bool: 
  10.         if not root: return True 
  11.         return abs(self.depth(root.left) - self.depth(root.right)) <= 1 and \ 
  12.             self.isBalanced(root.leftand self.isBalanced(root.right
  13.  
  14.     def depth(self, root): 
  15.         if not root: return 0 
  16.         return max(self.depth(root.left), self.depth(root.right)) +  

但是時(shí)間復(fù)雜度卻是,可以采用DFS(深度優(yōu)先搜索)

  • 對(duì)二叉樹(shù)做深度優(yōu)先遍歷DFS,遞歸過(guò)程中:
  • 終止條件:當(dāng)DFS越過(guò)葉子節(jié)點(diǎn)時(shí),返回高度0;
  • 返回值:從底至頂,返回以每個(gè)節(jié)點(diǎn)root為根節(jié)點(diǎn)的子樹(shù)最大高度(左右子樹(shù)中最大的高度值加1 max(left,right) + 1);
  • 當(dāng)我們發(fā)現(xiàn)有一例 左/右子樹(shù)高度差 > 1 的情況時(shí),代表此樹(shù)不是平衡樹(shù),返回-1;
  • 當(dāng)發(fā)現(xiàn)不是平衡樹(shù)時(shí),后面的高度計(jì)算都沒(méi)有意義了,因此一路返回-1,避免后續(xù)多余計(jì)算。

最差情況是對(duì)樹(shù)做一遍完整DFS,時(shí)間復(fù)雜度為 O(N)。

  1. class Solution: 
  2.     def isBalanced(self, root: TreeNode) -> bool: 
  3.         return self.depth(root) != -1 
  4.  
  5.     def depth(self, root): 
  6.         if not root: return 0 
  7.         left = self.depth(root.left
  8.         if left == -1: return -1 
  9.         right = self.depth(root.right
  10.         if right == -1: return -1 
  11.         return max(leftright) + 1 if abs(left - right) < 2 else -1 

本文已收錄 GitHub https://github.com/MaoliRUNsen/runsenlearnpy100更多的文章

 

責(zé)任編輯:姜華 來(lái)源: Python之王
相關(guān)推薦

2021-09-15 07:56:32

二叉樹(shù)層次遍歷

2020-04-27 07:05:58

二叉樹(shù)左子樹(shù)右子樹(shù)

2009-08-11 13:29:57

C#二叉樹(shù)遍歷

2022-10-26 23:58:02

二叉樹(shù)數(shù)組算法

2021-04-20 08:37:14

數(shù)據(jù)結(jié)構(gòu)二叉樹(shù)樹(shù)

2023-05-08 15:57:16

二叉樹(shù)數(shù)據(jù)結(jié)構(gòu)

2021-09-15 07:40:50

二叉樹(shù)數(shù)據(jù)結(jié)構(gòu)算法

2021-04-19 07:47:42

數(shù)據(jù)結(jié)構(gòu)二叉樹(shù)Tree

2024-01-23 12:54:00

C++編程語(yǔ)言代碼

2021-07-13 11:32:41

二叉樹(shù)數(shù)據(jù)結(jié)構(gòu)算法

2021-03-17 08:19:22

二叉樹(shù)LeetCode樹(shù)

2013-07-15 16:35:55

二叉樹(shù)迭代器

2021-04-28 20:12:27

數(shù)據(jù)結(jié)構(gòu)創(chuàng)建

2021-08-27 11:36:44

二叉樹(shù)回溯節(jié)點(diǎn)

2021-09-29 10:19:00

算法平衡二叉樹(shù)

2020-09-23 18:25:40

算法二叉樹(shù)多叉樹(shù)

2018-03-15 08:31:57

二叉樹(shù)存儲(chǔ)結(jié)構(gòu)

2021-05-06 17:46:30

二叉樹(shù)數(shù)據(jù)結(jié)構(gòu)

2021-10-12 09:25:11

二叉樹(shù)樹(shù)形結(jié)構(gòu)

2021-03-22 08:23:29

LeetCode二叉樹(shù)節(jié)點(diǎn)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)