剑指offer——树的子结构(JAVA代码)

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

剑指offer——树的⼦结构(JAVA代码)
版权声明:本⽂为博主原创⽂章,未经博主允许不得转载。

题⽬描述:
输⼊两棵⼆叉树A,B,判断B是不是A的⼦结构。

(ps:我们约定空树不是任意⼀个树的⼦结构)。

解题思路:
⾸先看⽜客⽹给出的测试⽤例:
⼀般对于树的操作不像链表⼀样,操作更复杂,如果使⽤循环遍历的话,对于⾮完全⼆叉树规律难寻,⼀般通⽤的⽅法就是使⽤递归求解,本题也不例外,同样使⽤递归求解,求解的⼤体思路是⾸先判断B的根节点和A的根节点是否相同(这⾥的相同是指节点的值相同并且左右⼦节点相同),如果相同⽐较他们的左右⼦节点,这⼀步骤是相同的,可以⽤递归完成,直到B遍历到每个尾节点,如果这⼀过程⽐较的所有节点是相同的,则证明B是A的⼦结构。

如果B的根节点和A的根节点不同,则A向他的左右⼦节点滑动,然后继续跟B的⼦节点⽐较,步骤同上。

递归的使⽤可以⽤我总结的三步来完成。

求解过程如下:
1. 递归截⽌条件。

递归的截⽌条件是为了递归能够避免⽆限循环下去,⾸先来分析什么情况下递归截⽌返回遍历结果,(1)根据题⽬要求,如果B数是个空树,递归截⽌。

(2)如果被遍历的树A是空树,⾃然⽽然递归截⽌。

(3)如果⽐较的是B的尾节点,⽆法进⾏下去,递归也会截⽌。

(4)如果A树从头遍历到尾始终没有和B的节点相同的节点,递归截⽌。

2. 递归的前后衔接。

如果A的根节点值以及左右⼦节点情况和B的根节点完全相同,那么A和B都继续滑动到他们的左右⼦节点进⾏⽐较;如果A的根节点值和B的根节点值是相同的,但是左右⼦节点的情况是不相同的,那么只滑动A到他的左右⼦节点再与B⽐较。

如果A的根节点的值和B的根节点的值不相同,那么A直接滑动到他的左右⾃⼰点再和B的根节点⽐较,直到遍历完成。

3. 递归节点数据的处理。

根据题⽬,本题⽬中⽤到的递归并没有数据处理,只是⽐较判断两个树节点是否相同。

对于其他递归,可以具体情况具体对待。

源码:
1/**
2 * 输⼊两棵⼆叉树A,B,判断B是不是A的⼦结构。

3 * @param root1 A树
4 * @param root2 B数
5 * @return
6*/
7public static boolean HasSubtree(TreeNode root1,TreeNode root2) {
8
9if (root2==null) { //空树不是任意⼀个树的⼦结构
10return false;
11 }
12if (root1==null) { //如果A为空,那肯定返回false
13return false;
14 }
15if(root2.val==root1.val){ //A和B⽐较的根节点的值相同
16
17if (root2.left==null&&root2.right==null) { //⽐较的节点是B的尾节点,递归截⽌
18return true;
19 }
20//下⾯三种⽐较的是⽐较的节点完全相同的情况
21if ((root2.left!=null&&root2.right!=null)&&(root1.left!=null&&root1.right!=null)&&root2.left.val==root1.left.val&&root2.right.val==root1.right.val) {
22return HasSubtree(root1.left,root2.left)&& HasSubtree(root1.right,root2.right);
23 }else if ((root2.left!=null&&root2.right==null)&&(root1.left!=null&&root1.right==null)&&root2.left.val==root1.left.val) {
24return HasSubtree(root1.left,root2.left);
25 }else if ((root2.left==null&&root2.right!=null)&&(root1.left==null&&root1.right!=null)&&root2.right.val==root1.right.val) {
26return HasSubtree(root1.right,root2.right);
27 }else{ //⽐较的节点不同,A向左右⼦节点移动⼀个再⽐较
28if (root1.left!=null&&root1.right!=null) {
29return HasSubtree(root1.left,root2)|| HasSubtree(root1.right,root2);
30 }else if(root1.left==null&&root1.right!=null){
31return HasSubtree(root1.right,root2);
32 }else if(root1.left!=null&&root1.right==null){ 33return HasSubtree(root1.left,root2);
34 }else {
35return false;
36 }
37 }
38//⽐较的根节点的值不相同,直接向左右⼦节点滑动39 }else if(root1.left!=null&&root1.right==null){
40return HasSubtree(root1.left,root2);
41 }else if(root1.left==null&&root1.right!=null){
42return HasSubtree(root1.right,root2);
43 }else{
44return false;
45 }
46 }。

相关文档
最新文档