題目
輸入兩棵二叉樹 A 和 B,判斷 B 是不是 A 的子結構。
如下給你兩棵樹:
問題分析
我們要判斷一個二叉樹是否爲另一個二叉樹的子結構,如圖,判斷二叉樹 B 是否爲二叉樹 A 的子結構,就需要從二叉樹的 A 的根節點和二叉樹 B 的根節點起開始判斷。
如果兩個二叉樹的根節點相同的時候,我們就分別遞歸判斷剩餘的結點是否相同,如果相同,則 B 爲 A 的子結構,否則,我們就判斷其他的 A 的子結構是否和 B 的結構相同。
既然問題我們已經分析清楚了,我們開始手寫代碼。
動畫實現
代碼拆解
第一步,判斷傳入的兩棵樹是否爲空,如果 A 樹爲空,則返回null。如果 B 樹爲空,則是 A 樹的子結構返回 true。
1// 匹配的返回值
2const result = false;
3
4// 判斷兩棵樹是否爲空
5if(NodeA == null || NodeB == null){
6 return null;
7}
第二步,如果兩棵樹不爲空,則判斷兩棵樹的根節點是否相同。
1// 根節點相等就進行匹配
2if(NodeA.data == NodeB.data){
3 result = match(NodeA,NodeB);
4}
第三步,如果兩棵樹的根節點相同,則進行匹配。匹配過程是一個遞歸的過程。
1// 開始匹配
2const match = (NodeA,NodeB)=>{
3 // 終止條件
4 if(nodeB == null){
5 return true;
6 }
7 if(nodeA == null){
8 return false;
9 }
10 // 如果匹配的當前結點相等,繼續匹配下面的結點
11 if(nodeA.data == nodeB.data){
12 return match(NodeA.left,NodeB.left) && match(NodeA.right,NodeB.right);
13 }else{
14 return false;
15 }
16}
第四步,如果兩棵樹根節點不相同,則也對其餘節點進行遞歸遍歷,找其他樹節點是否存在根節點相同的節點。
1 // 判斷上述過程是否匹配成功
2 if(result){
3 return true;
4 }
5 // 繼續匹配其他節點
6 return matchTree(NodeA.left,NodeB) || matchTree(NodeA.right,NodeB)
代碼實現
JavaScript 版本
Java 版本
Python 版本
測試用例
- 是子結構、不是子結構 —— 普通測試。
- 只有左子節點、只有右子節點、只有一個結點 —— 特殊測試。
- 空樹 —— 輸入測試。