樹的遞迴思想套路使用
阿新 • • 發佈:2022-04-13
* 二叉樹的遞迴套路總結(遞迴的最核心思想:通過遞迴,可以把任何問題都簡化為根節點,左兒子,右兒子的問題
* 即:把左右子樹通過遞迴給歸一化為左右兒子節點(把整棵樹看作一個整體))
* 1.進行遞迴,分別從根節點向左子樹和右子樹進行遞迴(對任何問題通用)
* 2.分析題目所要求的條件,去根據題目要求得到根節點,左子樹和右子樹的邏輯關係,並在每一次遞迴中將這種
* 關係給模擬出來(因為使用了遞迴,其實就可以把一整棵子樹看作一個節點來進行考慮)
*
* 補充:因為我們通常是把一棵子樹抽象成一個節點來進行考慮,一般來說這個節點要儲存多個所需要的值,所以一般
* 都要自己去定義一個返回型別,讓所有需要的值都能在遞迴中返回傳遞
舉例分析:
例子1:
平衡二叉樹:任意節點的左子樹和右子樹的高度差小於等於1
判斷一棵樹是否為平衡二叉樹
* 套路解析:
* 1.確認遞迴的方式:從某個節點遞迴到它的左兒子節點和右兒子節點
* 2.對每個節點的分析(要拆分遞迴):即該節點的左子樹和右子樹的高度差小於等於1
程式碼:
1 public static class ReturnType{//定義一個特殊的返回型別,能同時返回這棵樹的最大高度和是否平衡 2 public int height; 3 public boolean isBalance; 4 5 publicReturnType(int height,boolean isBalance) { 6 this.height = height; 7 this.isBalance = isBalance; 8 } 9 } 10 11 //執行遞迴過程 12 public static ReturnType process(Node root) { 13 if (root == null) { 14 return new ReturnType(0,true); 15 }16 //對左右子樹進行遞迴 17 ReturnType lt = process(root.left); 18 ReturnType rt = process(root.right); 19 //對每一次遞迴進行具體的判斷分析 20 int height = Math.max(lt.height, rt.height) + 1; 21 //只有當左子樹平衡,右子樹平衡,且兩樹高度差小於1時,這棵樹才平衡 22 boolean isBalance = lt.isBalance && rt.isBalance && (Math.abs(rt.height - lt.height) <= 1); 23 return new ReturnType(height,isBalance); 24 } 25 //原函式 26 public static boolean isBalanceTree(Node root) { 27 return process(root).isBalance; 28 }
例子2:
判斷一棵樹是否為搜尋二叉樹:
1.遞迴判斷左樹和右樹是否為搜尋二叉樹
2.判斷根節點是否大於左樹的最大值(這個最大值因為有了遞迴,所以不用遍歷整棵樹,只要在每次遞迴時都把這個值儲存住,一直遞迴傳遞即可),是否小於右樹的最小值
1 public static class DataType{ 2 public boolean isBST; 3 public int max;//用於左樹求最大值 4 public int min;//用於右樹求最小值 5 6 public DataType(boolean isBST,int max,int min) { 7 this.isBST = isBST; 8 this.max = max; 9 this.min = min; 10 } 11 } 12 13 public static DataType process1(Node root) { 14 if (root == null) { 15 return null; 16 } 17 //分別獲得左右樹的資訊 18 DataType ld = process1(root.left); 19 DataType rd = process1(root.right); 20 21 //進行比較分析處理 22 int min = root.val, max = root.val; 23 boolean isBST = true; 24 //通過以下操作就可以得到整棵樹的最小值和最大值(必須要得到,因為這棵樹也可能是子樹,用於下一步的遞迴返回) 25 if (ld != null) { 26 min = Math.min(min, ld.min); 27 max = Math.max(max, ld.max); 28 } 29 if (rd != null) { 30 min = Math.min(min, rd.min); 31 max = Math.max(max, rd.max); 32 } 33 //判斷是否為搜尋二叉樹 34 if (ld != null && (ld.isBST == false || ld.max > root.val)) {//若左樹不為空,且不是搜尋二叉樹 35 //或左樹最大值大於根節點的值 36 isBST = false; 37 } 38 if (rd != null && (rd.isBST == false || rd.min < root.val)) {//若右樹不為空,且不是搜尋二叉樹 39 //或右樹最小值小於根節點的值 40 isBST = false; 41 } 42 return new DataType(isBST,max,min); 43 }