判断一棵树是否是另一棵树的子树

问题

判断一棵树是否是另一棵树的子树,如图

思路

问题分两步:

  • 找值相同的根结点(遍历解决)
  • 判断两结点是否包含(递归:值、左孩子、右孩子分别相同)

代码

bool IsPart(TreeNode *root1, TreeNode *root2)
{
    if (root2 == NULL)
        return true;
    if (root1 == NULL)
        return false;
    if (root1->val != root2->val)
        return false;
    return IsPart(root1->left, root2->left) &&
        IsPart(root1->right, root2->right);
}
bool IsPartTree(TreeNode *root1, TreeNode *root2)
{
    bool result = false;
    if (root1 != NULL && root2 != NULL)
    {
        if (root1->val == root2->val)
            result = IsPart(root1, root2);
        if (!result)
            result = IsPartTree(root1->left, root2);
        if (!result)
            result = IsPartTree(root1->right, root2);
    }
    return result;
}

执行

#include <iostream>
#include <stack>
using namespace std;
struct TreeNode
{
    int val;
    TreeNode *left;
    TreeNode *right;
    TreeNode(int v) : val(v), left(NULL), right(NULL) {}
};
bool IsPart(TreeNode *root1, TreeNode *root2)
{
    if (root2 == NULL)
        return true;
    if (root1 == NULL)
        return false;
    if (root1->val != root2->val)
        return false;
    return IsPart(root1->left, root2->left) &&
        IsPart(root1->right, root2->right);
}
bool IsPartTree(TreeNode *root1, TreeNode *root2)
{
    bool result = false;
    if (root1 != NULL && root2 != NULL)
    {
        if (root1->val == root2->val)
            result = IsPart(root1, root2);
        if (!result)
            result = IsPartTree(root1->left, root2);
        if (!result)
            result = IsPartTree(root1->right, root2);
    }
    return result;
}
TreeNode* createTree1()
{
    TreeNode *root = new TreeNode(1);
    TreeNode *p1 = new TreeNode(2);
    TreeNode *p2 = new TreeNode(3);
    TreeNode *p3 = new TreeNode(4);
    TreeNode *p4 = new TreeNode(5);
    root->left = p1;
    root->right = p2;
    p2->left = p3;
    p2->right = p4;
    return root;
}
TreeNode* createTree2()
{
    TreeNode *root = new TreeNode(1);
    TreeNode *p1 = new TreeNode(2);
    TreeNode *p2 = new TreeNode(3);
    root->left = p1;
    root->right = p2;
    return root;
}

void deleteTree(TreeNode *root)
{
    if (root != NULL)
    {
        delete(root->left);
        delete(root->right);
        delete root;
        root = NULL;
    }
}
int main()
{
    TreeNode *root1 = createTree1();
    TreeNode *root2 = createTree2();
    cout << IsPartTree(root1, root2) << endl;
    deleteTree(root1);
    deleteTree(root2);
}

推荐

算法与数据结构索引

时间: 2024-10-26 21:46:12

判断一棵树是否是另一棵树的子树的相关文章

比较两棵二叉树--(比较两棵二叉树是否相同/判断一棵二叉树是否是另一棵二叉树的子树)

一,问题介绍 本文章讨论两个问题: ①如何判断两棵二叉树的结构是一样的.对应的每个结点都有着相同的值.--即判断两棵二叉树是一样的 ②给定两棵二叉树,如何判断一棵二叉树是另一棵二叉树的子结构 ③给定两棵二叉树,如何判断一棵二叉树是另一棵二叉树的子树 注意,子结点与子树有那么一点点不同. 上面的二叉树B 是二叉树A 的子结构,但是不能说是二叉树A的子树.但是二叉树C 是 二叉树A的子树. 二,问题分析 1,如何判断两棵二叉树的结构是一样的.且对应的每个结点都有着相同的值. 对于①如何判断两棵二叉树

判断一个整数不是2的阶次方树

如果是一个2的阶次方,那么它的二进制数的首位一般是1,后面接若干个0.比如8就是1000,64是100 0000. 如果将这个数减1后,再与该数做和&运算,则改全为0. package cn.usst.DataTest; import java.io.*; /** * 从键盘输入一个值 */ public class InputData { static private String s = ""; static public void input() { BufferedRe

[1]输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表

输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表.要求不能创建任何新的结点,只调整指针的指向.          10        /     \       6     14      / \     /  \     4  8 12  16转换成双向链表4=6=8=10=12=14=16 解: 二元查找树: 它首先要是一棵二元树,在这基础上它或者是一棵空树:或者是具有下列性质的二元树: (1)若左子树不空,则左子树上所有结点的值均小于它的根结点的值: (2)若右子树不空,则右子树

AVL树,红黑树,B-B+树,Trie树原理和应用

前言:本文章来源于我在知乎上回答的一个问题 AVL树,红黑树,B树,B+树,Trie树都分别应用在哪些现实场景中? 看完后您可能会了解到这些数据结构大致的原理及为什么用在这些场景,文章并不涉及具体操作(如插入删除等等) 目录 AVL树 AVL树原理与应用 红黑树 红黑树原理与应用 B/B+树 B/B+树原理与应用 Trie树 Trie树原理与应用 AVL树 简介: AVL树是最早的自平衡二叉树,在早期应用还相对来说比较广,后期由于旋转次数过多而被红黑树等结构取代(二者都是用来搜索的),AVL树内

BZOJ 2243:染色(树链剖分+区间合并线段树)

[SDOI2011]染色Description给定一棵有n个节点的无根树和m个操作,操作有2类:1.将节点a到节点b路径上所有点都染成颜色c:2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段),如“112221”由3段组成:“11”.“222”和“1”.请你写一个程序依次完成这m个操作.Input第一行包含2个整数n和m,分别表示节点数和操作数:第二行包含n个正整数表示n个节点的初始颜色下面 行每行包含两个整数x和y,表示x和y之间有一条无向边.下面 行每行描述一个操作:“C

Java实现二叉搜索树的添加,前序、后序、中序及层序遍历,求树的节点数,求树的最大值、最小值,查找等操作

什么也不说了,直接上代码. 首先是节点类,大家都懂得 /** * 二叉树的节点类 * * @author HeYufan * * @param <T> */ class Node<T extends Comparable<? super T>> { /** * 节点储存的值 */ private T data; /** * 左子节点 */ private Node<T> leftNode; /** * 右子节点 */ private Node<T>

javascript实现数据结构: 树和二叉树的应用--最优二叉树(赫夫曼树),回溯法与树的遍历--求集合幂集及八皇后问题

赫夫曼树及其应用 赫夫曼(Huffman)树又称最优树,是一类带权路径长度最短的树,有着广泛的应用. 最优二叉树(Huffman树) 1 基本概念 ① 结点路径:从树中一个结点到另一个结点的之间的分支构成这两个结点之间的路径. ② 路径长度:结点路径上的分支数目称为路径长度. ③ 树的路径长度:从树根到每一个结点的路径长度之和. 以下图为例: A到F :结点路径 AEF : 路径长度(即边的数目) 2 : 树的路径长度:3*1+5*2+2*3=19: ④ 结点的带权路径长度:从该结点的到树的根结

【编程题目】把二元查找树转变成排序的双向链表(树)

1.把二元查找树转变成排序的双向链表(树)题目:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表.要求不能创建任何新的结点,只调整指针的指向. 10 / \ 6 14 / \ / \ 4 8 12 16转换成双向链表4=6=8=10=12=14=16.首先我们定义的二元查找树 节点的数据结构如下:struct BSTreeNode{int m_nValue; // value of nodeBSTreeNode *m_pLeft; // left child of nodeBSTree

【BZOJ2653】middle,主席树(非权值线段树)维护区间01信息+二分答案

传送门 写在前面:虽然这是一道我再也不想写的题目,但很好很有价值 思路: cxlove大神: 要求中位数最大,首先二分中位数,然后判断可行不可行. 判断X可行不可行,对于区间内的数,凡是>=X的标为1,否则为-1.这样的话,求一次最大区间和 如果大于等于0,则说明可行. 这要求我们不能像之前那样建立权值线段树的主席树(区间即为权值)了,而是以权值为下标,维护区间[1,n]的信息,可能有点拗口,这里就理解是我们平常写的普通线段树好了,只是这里是n棵由于根的不同而信息不同的线段树 具体实现 对于题目