首页 > 试题广场 >

判断t1树是否包含t2树全部的拓扑结构

[编程题]判断t1树是否包含t2树全部的拓扑结构
  • 热度指数:1104 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
给定彼此独立的两棵二叉树,判断 t1 树是否包含 t2 树全部的拓扑结构。
设 t1 树的边集为 E1,t2 树的边集为 E2,若 E2 是 E1 的子集,则表示 t1 树包含 t2 树全部的拓扑结构。

输入描述:
第一行输入两个整数 n 和 root,n 表示二叉树 t1 的总节点个数,root 表示二叉树 t1 的根节点。

以下 n 行每行三个整数 fa,lch,rch,表示 fa 的左儿子为 lch,右儿子为 rch。(如果 lch 为 0 则表示 fa 没有左儿子,rch同理)

第 n+2 行输入两个整数 m 和 root,n 表示二叉树 t2 的总节点个数,root 表示二叉树 t2 的根节点。

以下 m 行每行三个整数 fa,lch,rch,表示 fa 的左儿子为 lch,右儿子为 rch。(如果 lch 为 0 则表示 fa 没有左儿子,rch同理)


输出描述:
如果 t1 树包含 t2 树全部的拓扑结构,则输出 "true",否则输出 "false"。
示例1

输入

10 1
1 2 3
2 4 5
4 8 9
8 0 0
9 0 0
5 10 0
10 0 0
3 6 7
6 0 0
7 0 0
4 2
2 4 5
5 0 0
4 8 0
8 0 0

输出

true

备注:

这个题比判断子树那个更简单一些:
  1. 只有在B树节点全部检查完,无跟A树节点有不相等的情况才返回true;
  2. 如果B树节点还没检查完A树就没有节点了,说明A树剩下的规模已经不足以囊括B树的拓扑结构,返回false;
  3. A树和B树节点值相等,继续检查下面的节点值;
  4. A树和B树节点值不相等,检查B树拓扑结构是否在A树的子树之中。
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
import java.util.HashMap;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        // 构建树A
        String[] params = br.readLine().split(" ");
        int n = Integer.parseInt(params[0]);
        TreeNode treeA = new TreeNode(Integer.parseInt(params[1]));
        HashMap<Integer, TreeNode> map = new HashMap<>();
        map.put(treeA.val, treeA);
        for(int i = 0; i < n; i++){
            params = br.readLine().split(" ");
            int val = Integer.parseInt(params[0]);
            int leftVal = Integer.parseInt(params[1]);
            int rightVal = Integer.parseInt(params[2]);
            TreeNode node = map.get(val);
            if(leftVal != 0) {
                node.left = new TreeNode(leftVal);
                map.put(leftVal, node.left);
            }
            if(rightVal != 0) {
                node.right = new TreeNode(rightVal);
                map.put(rightVal, node.right);
            }
        }
        // 构建树B
        params = br.readLine().split(" ");
        int m = Integer.parseInt(params[0]);
        TreeNode treeB = new TreeNode(Integer.parseInt(params[1]));
        map.clear();
        map.put(treeB.val, treeB);
        for(int i = 0; i < m; i++){
            params = br.readLine().split(" ");
            int val = Integer.parseInt(params[0]);
            int leftVal = Integer.parseInt(params[1]);
            int rightVal = Integer.parseInt(params[2]);
            TreeNode node = map.get(val);
            if(leftVal != 0) {
                node.left = new TreeNode(leftVal);
                map.put(leftVal, node.left);
            }
            if(rightVal != 0) {
                node.right = new TreeNode(rightVal);
                map.put(rightVal, node.right);
            }
        }
        System.out.println(isSubTopology(treeA, treeB));
    }
    
    private static boolean isSubTopology(TreeNode treeA, TreeNode treeB) {
        if(treeB == null) return true;      // B树节点检查完了返回true
        if(treeA == null) return false;     // B树节点没检查完A树就没节点了返回false
        if(treeA.val == treeB.val){
            // 节点值相等就继续检查下面的节点
            return isSubTopology(treeA.left, treeB.left) && isSubTopology(treeA.right, treeB.right);
        }else{
            // 不相等就检查B树的拓扑结构是不是在A树的子树中
            return isSubTopology(treeA.left, treeB) || isSubTopology(treeA.right, treeB);
        }
    }
}

class TreeNode {
    public int val;
    public TreeNode left;
    public TreeNode right;
    public TreeNode(int val) {
        this.val = val;
    }
}

发表于 2021-12-04 10:05:40 回复(0)
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

public class Main {

    public static int n, m , root1, root2;
    public static Node[] nodes1, nodes2;

    public static class Node {
        int val, left, right;
        Node(int val, int left, int right) {
            this.val = val;
            this.left = left;
            this.right = right;
        }
    }

    public static boolean contain(int index1, int index2) {
        Queue<Integer> queue = new LinkedList<>();
        queue.offer(index2);
        while (!queue.isEmpty()) {
            int front = queue.poll();
            int left1 = nodes1[front].left;
            int right1 = nodes1[front].right;
            int left2 = nodes2[front].left;
            int right2 = nodes2[front].right;
            if (left2 != 0) {
                if (left1 != left2) return false;
                queue.offer(left2);
            }
            if (right2 != 0) {
                if (right1 != right2) return false;
                queue.offer(right2);
            }
        }
        return true;
    }

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        n = input.nextInt();
        root1 = input.nextInt();
        nodes1 = new Node[n+1];
        for (int i = 0; i < n; i++) {
            int val = input.nextInt();
            int left = input.nextInt();
            int right = input.nextInt();
            nodes1[val] = new Node(val, left, right);
        }
        m = input.nextInt();
        root2 = input.nextInt();
        nodes2 = new Node[n+1];
        boolean flag = false;
        for (int i = 0; i < m; i++) {
            int val = input.nextInt();
            flag = val > n;
            int left = input.nextInt();
            int right = input.nextInt();
            nodes2[val] = new Node(val, left, right);
        }
        if (flag) {
            System.out.println(false);
            return;
        }
        System.out.println(contain(root1, root2));
    }
}

发表于 2020-08-05 21:58:20 回复(0)
#include<iostream>
using namespace std;
struct TreeNode{
    int val;
    TreeNode* left;
    TreeNode* right;
};
void CreateTree(TreeNode* pRoot,int& n){
    if(n==0){
        return;
    }
    int rootval,leftval,rightval;
    cin>>rootval>>leftval>>rightval;
    if(leftval!=0){
        TreeNode* leftnode = new TreeNode;
        leftnode->val = leftval;
        leftnode->left=leftnode->right=nullptr;
        pRoot->left = leftnode;
        CreateTree(leftnode,--n);
    }
    if(rightval!=0){
        TreeNode* rightnode = new TreeNode;
        rightnode->val = rightval;
        rightnode->left=rightnode->right=nullptr;
        pRoot->left = rightnode;
        CreateTree(rightnode,--n);
    }
}
bool Tree1HasTree2(TreeNode* pRoot1,TreeNode* pRoot2){
    if(pRoot2==nullptr){
        return true;
    }
    if(pRoot1==nullptr){
        return false;
    }
    if(pRoot1->val!=pRoot2->val){
        return false;
    }
    return Tree1HasTree2(pRoot1->left, pRoot2->left) && Tree1HasTree2(pRoot1->right, pRoot2->right);
}
bool HasSubTree(TreeNode* pRoot1,TreeNode* pRoot2){
    if(pRoot2==nullptr){
        return true;
    }
    if(pRoot1==nullptr){
        return false;
    }
    bool flag = false;
    if(pRoot1->val==pRoot2->val){
        flag = Tree1HasTree2(pRoot1,pRoot2);
    }
    if(!flag && pRoot1->left!=nullptr){
        flag = HasSubTree(pRoot1->left, pRoot2);
    }
    if(!flag && pRoot1->right!=nullptr){
        flag = HasSubTree(pRoot1->right, pRoot2);
    }
    return flag;
}

int main(){
    int n1,rootval1;
    cin>>n1>>rootval1;
    TreeNode* pRoot1 = new TreeNode;
    pRoot1->val = rootval1;
    pRoot1->left = pRoot1->right = nullptr;
    TreeNode* pCurrNode1 = pRoot1;
    CreateTree(pCurrNode1,n1);
    //cout<<"true";
    int n2,rootval2;
    cin>>n2>>rootval2;
    TreeNode* pRoot2 = new TreeNode;
    pRoot2->val = rootval2;
    pRoot2->left = pRoot2->right = nullptr;
    TreeNode* pCurrNode2 = pRoot2;
    CreateTree(pCurrNode2,n2);
    //cout<<"true";
    if(HasSubTree(pCurrNode1,pCurrNode2)){
        cout<<"true";
    }else{
        cout<<"false";
    }
    return 0;
}


发表于 2020-07-29 15:24:14 回复(0)
#include <iostream>

using namespace std;

struct TreeNode {
    int val;
    TreeNode* left;
    TreeNode* right;
    TreeNode(int x): val(x), left(NULL), right(NULL) {}
}; 

void createTree(TreeNode* root, int& n) {
    if(root == nullptr)
        return ;
    int rootVal, leftVal, rightVal;
    cin >> rootVal >> leftVal >> rightVal;
    if(leftVal != 0) {
        TreeNode* leftNode = new TreeNode(leftVal);
        leftNode->left = leftNode->right = nullptr;
        root->left = leftNode;
        createTree(leftNode, --n);
    }
    if(rightVal != 0) {
        TreeNode* rightNode = new TreeNode(rightVal);
        rightNode->left = rightNode->right = nullptr;
        root->right = rightNode;
        createTree(rightNode, --n);
    }
    return ;
}

bool isSametree(TreeNode* root, TreeNode* subRoot) {
        if(subRoot == nullptr)
            return true;
        if(root == nullptr)
            return false;
        if(root->val != subRoot->val)
            return false;
        bool inside = isSametree(root->left, subRoot->left);
        bool outside = isSametree(root->right, subRoot->right);
        return inside && outside;
    }

bool isSubtree(TreeNode* root, TreeNode* subRoot) {
        if(subRoot == nullptr)
            return true;
        if(root == nullptr)
            return false;
        return isSametree(root, subRoot) || isSubtree(root->left, subRoot) || isSubtree(root->right, subRoot);
    }


int main() {
    int n1, rootVal1;
    cin >> n1 >> rootVal1;
    TreeNode* rootA = new TreeNode(rootVal1);
    rootA->left = rootA->right = nullptr;
    createTree(rootA, n1);
    
    int n2, rootVal2;
    cin >> n2 >> rootVal2;
    TreeNode* rootB = new TreeNode(rootVal2);
    rootB->left = rootB->right = nullptr;
    createTree(rootB, n2);
    if(isSubtree(rootA, rootB))
        cout << "true";
    else
        cout << "false";
    return 0;
}

发表于 2022-06-09 18:50:14 回复(0)
#include <stdio.h>
#include <stdlib.h>

typedef struct {
  int parent, l_child, r_child;
} TreeNodeInfo, *Infos;

int judge(Infos A, Infos B, int a_id, int b_id) { // judge B树是否是A树的子集
  if (!a_id && !b_id) return 1;
  if (!a_id) return 0;
  if (!b_id) return 1;
  return a_id == b_id
    && judge(A, B, A[a_id].l_child, B[a_id].l_child)
    && judge(A, B, A[a_id].r_child, B[a_id].r_child);
}

int isSubStructure(Infos A, Infos B, int a_id, int b_id) {
  if (!a_id) return 0;
  return judge(A, B, a_id, b_id)
    || isSubStructure(A, B, A[a_id].l_child, b_id)
    || isSubStructure(A, B, A[a_id].r_child, b_id);
}

int main(const int argc, const char* const argv[]) {
  int n, m, root_1_id, root_2_id;
  int fa, l_ch, r_ch;
  
  fscanf(stdin, "%d %d", &n, &root_1_id);
  TreeNodeInfo root1[n + 1];
  int x = n;
  while (x--) {
    fscanf(stdin, "%d %d %d", &fa, &l_ch, &r_ch);
    (*(root1 + fa)).l_child = l_ch;
    (*(root1 + fa)).r_child = r_ch;
  }
  
  fscanf(stdin, "%d %d", &m, &root_2_id);
  TreeNodeInfo root2[n + 1];
  while (m--) {
    fscanf(stdin, "%d %d %d", &fa, &l_ch, &r_ch);
    (*(root2 + fa)).l_child = l_ch;
    (*(root2 + fa)).r_child = r_ch;
  }
  
  printf("%s", isSubStructure(root1, root2, root_1_id, root_2_id) ? "true" : "false");
  return 0;
}

发表于 2021-07-24 18:38:36 回复(0)
#数据的输入处理
#树1
n, r1 = list(map(int, input().split()))
#将树定义为字典
tree1 = {}
for _ in range(n):
    x, left, right = list(map(int, input().split()))
    #以元祖的形式定义子树
    tree1[x] = (left, right)
#树2
m, r2 = list(map(int, input().split()))
tree2 = {}
for _ in range(m):
    x, left, right = list(map(int, input().split()))
    tree2[x] = (left, right)
    
# ==============================
#检查x,以及它作为根时的子树是否在tree 1里面
def checkNode(x) -> bool: 
    if not x in tree1:
        return False
    #取出子树
    l2, r2 = tree2[x]
    #如果子树非空,但是不在树1中
    if l2 and l2 not in tree1[x]:
        return False
    if r2 and r2 not in tree1[x]:
        return False
    return True
# 遍历tree 2, 查每个节点和它左右的链接
def bfs(tree, root): 
    queue = [root]
    #层次遍历
    while queue:
        x = queue.pop()
        if not checkNode(x):
            return False
 
        if tree[x][0]: # left
            queue.append(tree[x][0])
        if tree[x][1]: # right
            queue.append(tree[x][1])
    
    return True

if bfs(tree2, r2):
    print('true')
else:
    print('false')
    
    

发表于 2021-06-14 19:13:11 回复(0)
注意!!!!  这道题给的输入是错的
正确的输入应该是这样 :
10 1
1 2 3
2 4 5
4 8 9
8 0 0
9 0 0
5 10 0
10 0 0
3 6 7
6 0 0
7 0 0
4 2
2 4 5
4 8 0
8 0 0
5 0 0


发表于 2020-11-11 22:36:48 回复(0)
#include<bits/stdc++.h>
using namespace std;
bool judge(int root1,int root2,int* lc1,int* rc1,int* lc2,int* rc2)
{
    if(!root2) return true;
    if((!root1) || (root1!=root2)) return false;
    return judge(lc1[root1],lc2[root2],lc1,rc1,lc2,rc2) && judge(rc1[root1],rc2[root2],lc1,rc1,lc2,rc2);
}
bool visit(int root1,int root2,int* lc1,int* rc1,int* lc2,int* rc2)
{
    if(!root2) return true;
    if(!root1) return false;
    return judge(root1,root2,lc1,rc1,lc2,rc2) || visit(lc1[root1],root2,lc1,rc1,lc2,rc2) || visit(rc1[root1],root2,lc1,rc1,lc2,rc2); 
}
int main()
{
    int n,root1;
    cin>>n>>root1;
    int p;
    int* lc1 = new int[n+1];
    int* rc1 = new int[n+1];
    for(int i=0;i<n;++i)
    {
        cin>>p;
        cin>>lc1[p]>>rc1[p];
    }
    int m,root2;
    cin>>m>>root2;
    if(m>n)
    {
        cout<<"false"; return 0;
    }
    int* lc2 = new int[n+1];
    int* rc2 = new int[n+1];
    for(int j=0;j<m;++j)
    {
        cin>>p;
        cin>>lc2[p]>>rc2[p];
    }
    bool ans = visit(root1,root2,lc1,rc1,lc2,rc2);
    if(ans) cout<<"true";
    else cout<<"false";
    return 0;

}
发表于 2020-02-05 18:17:36 回复(0)