判断一个树对象是否是另个树的子树

106 阅读1分钟

T是S的子树 image.png

T不是S的子树 image.png

// treeNode为根树,childNode为子树
const treeNode = {
    val:'1',
    name:'祖先',
    age:100,
    left:{
        val:'L-1-1',
        name:'L-1-1-张三',
        age:65,
        left:{
            val:'L-1-1-1',
            name:'L-1-1-1-张三',
            age:40,
            left:{
                val:'L-1-1-1-1',
                name:'L-1-1-1-1-张三',
                age:20,
            }
        },
        right:{
            val:'R-1-1-1',
            name:'R-1-1-1-张三',
            age:40,
            left:{
                val:'R-1-1-1-1',
                name:'R-1-1-1-1-张三',
                age:20,
            }
        }
    },
}
const childNode = {
    val:'L-1-1',
    name:'L-1-1-张三',
    age:65,
    left:{
        val:'L-1-1-1',
        name:'L-1-1-1-张三',
        age:40,
        left:{
            val:'L-1-1-1-1',
            name:'L-1-1-1-1-张三',
            age:20,
        }
    },
    right:{
        val:'R-1-1-1',
        name:'R-1-1-1-张三',
        age:40,
        left:{
            val:'R-1-1-1-1',
            name:'R-1-1-1-1-张三',
            age:20,
        }
    }
}

思路:两棵树采用平行对比。 1.首先对比两树中的名称是否相同,不同则直接递归根树,直到找到名称相同的节点为止。 2.找到名称相同的节点后拿整个节点与目标树进行逐层各个属性对比,各层对比完成后即可得到最终结果。 主要代码如下:

function isSubtree(s ,t ){
     let  flag = false;
     //递归的出口条件
     if(s != null){
         if(s.name == t.name){ // 找出根树中名称与子树相同的节点
             flag = isSameTree(s,t);
         }
         //此时s还未遍历完,仍未找到s中为t的根节点的值的节点
         //递归的从子树中寻找
         if(!flag){
             flag = isSubtree(s.left,t) || isSubtree(s.right,t);
         }
     }
     return flag;
 }

// 两个同级别的树进行比较
function isSameTree( p,q){
    if(p == null && q == null){
        return true;
    }
    if(p == null || q == null){
        return false;
    }
    if(q.name != p.name || q.age != p.age){ // 比较name和age不同则直接返回false
        return false;
    }
    return isSameTree(p.left,q.left) && isSameTree(p.right,q.right);
}
console.log('结果',isSubtree(treeNode,childNode))