1. 程式人生 > 其它 >樹的遞迴思想套路使用

樹的遞迴思想套路使用

* 二叉樹的遞迴套路總結(遞迴的最核心思想:通過遞迴,可以把任何問題都簡化為根節點,左兒子,右兒子的問題
* 即:把左右子樹通過遞迴給歸一化為左右兒子節點(把整棵樹看作一個整體))
* 1.進行遞迴,分別從根節點向左子樹和右子樹進行遞迴(對任何問題通用)
* 2.分析題目所要求的條件,去根據題目要求得到根節點,左子樹和右子樹的邏輯關係,並在每一次遞迴中將這種
* 關係給模擬出來(因為使用了遞迴,其實就可以把一整棵子樹看作一個節點來進行考慮)
*
* 補充:因為我們通常是把一棵子樹抽象成一個節點來進行考慮,一般來說這個節點要儲存多個所需要的值,所以一般
* 都要自己去定義一個返回型別,讓所有需要的值都能在遞迴中返回傳遞

 

舉例分析:

例子1:

平衡二叉樹:任意節點的左子樹和右子樹的高度差小於等於1
判斷一棵樹是否為平衡二叉樹

* 套路解析:
* 1.確認遞迴的方式:從某個節點遞迴到它的左兒子節點和右兒子節點
* 2.對每個節點的分析(要拆分遞迴):即該節點的左子樹和右子樹的高度差小於等於1

程式碼:

 1 public static class ReturnType{//定義一個特殊的返回型別,能同時返回這棵樹的最大高度和是否平衡
 2         public int height;
 3         public boolean isBalance;
 4         
 5         public
ReturnType(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     }