// 面试题26:树的子结构
// 题目:输入两棵二叉树A和B,判断B是不是A的子结构。 #include <iostream> struct BinaryTreeNode
{
double m_dbValue;
BinaryTreeNode* m_pLeft;
BinaryTreeNode* m_pRight;
}; bool DoesTree1HaveTree2(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2);
bool Equal(double num1, double num2); bool HasSubtree(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2)//遍历树1,看看有没有树2的头结点
{
bool result = false; if (pRoot1 != nullptr && pRoot2 != nullptr)//对于树结构,时刻判断节点为空的情况
{
if (Equal(pRoot1->m_dbValue, pRoot2->m_dbValue))//注意该题树结构中值的类型是double,不能用==
result = DoesTree1HaveTree2(pRoot1, pRoot2);//如果头结点一样,就看看是否真的包含
if (!result)
result = HasSubtree(pRoot1->m_pLeft, pRoot2);//如果头结点不一样,就开始遍历全树
if (!result)
result = HasSubtree(pRoot1->m_pRight, pRoot2);
} return result;
} bool DoesTree1HaveTree2(BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2)
{
if (pRoot2 == nullptr)//如果这个节点为空代表什么,把树2熬到头就赢了
return true; if (pRoot1 == nullptr)//如果这个节点为空代表什么,完了,树1先熬到头了
return false; if (!Equal(pRoot1->m_dbValue, pRoot2->m_dbValue))//都在啊,那等不等啊
return false; return DoesTree1HaveTree2(pRoot1->m_pLeft, pRoot2->m_pLeft) &&
DoesTree1HaveTree2(pRoot1->m_pRight, pRoot2->m_pRight);//相等,那就递归的检测
} bool Equal(double num1, double num2)
{
if ((num1 - num2 > -0.0000001) && (num1 - num2 < 0.0000001))
return true;
else
return false;
} // ====================辅助测试代码====================
BinaryTreeNode* CreateBinaryTreeNode(double dbValue)
{
BinaryTreeNode* pNode = new BinaryTreeNode();
pNode->m_dbValue = dbValue;
pNode->m_pLeft = nullptr;
pNode->m_pRight = nullptr; return pNode;
} void ConnectTreeNodes(BinaryTreeNode* pParent, BinaryTreeNode* pLeft, BinaryTreeNode* pRight)
{
if (pParent != nullptr)
{
pParent->m_pLeft = pLeft;//这个时候不用说pLeft为不为空了,为空又怎样
pParent->m_pRight = pRight;
}
} void DestroyTree(BinaryTreeNode* pRoot)
{
if (pRoot != nullptr)
{
BinaryTreeNode* pLeft = pRoot->m_pLeft;
BinaryTreeNode* pRight = pRoot->m_pRight; delete pRoot;
pRoot = nullptr; DestroyTree(pLeft);
DestroyTree(pRight);
}
} // ====================测试代码====================
void Test(const char* testName, BinaryTreeNode* pRoot1, BinaryTreeNode* pRoot2, bool expected)
{
if (HasSubtree(pRoot1, pRoot2) == expected)
printf("%s passed.\n", testName);
else
printf("%s failed.\n", testName);
} //去吧,把能想到全想到 // 树中结点含有分叉,树B是树A的子结构
// 8 8
// / \ / \
// 8 7 9 2
// / \
// 9 2
// / \
// 4 7
void Test1()
{
BinaryTreeNode* pNodeA1 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeA2 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeA3 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeA4 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeA5 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeA6 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeA7 = CreateBinaryTreeNode(); ConnectTreeNodes(pNodeA1, pNodeA2, pNodeA3);
ConnectTreeNodes(pNodeA2, pNodeA4, pNodeA5);
ConnectTreeNodes(pNodeA5, pNodeA6, pNodeA7); BinaryTreeNode* pNodeB1 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeB2 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeB3 = CreateBinaryTreeNode(); ConnectTreeNodes(pNodeB1, pNodeB2, pNodeB3); Test("Test1", pNodeA1, pNodeB1, true); DestroyTree(pNodeA1);
DestroyTree(pNodeB1);
} // 树中结点含有分叉,树B不是树A的子结构
// 8 8
// / \ / \
// 8 7 9 2
// / \
// 9 3
// / \
// 4 7
void Test2()
{
BinaryTreeNode* pNodeA1 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeA2 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeA3 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeA4 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeA5 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeA6 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeA7 = CreateBinaryTreeNode(); ConnectTreeNodes(pNodeA1, pNodeA2, pNodeA3);
ConnectTreeNodes(pNodeA2, pNodeA4, pNodeA5);
ConnectTreeNodes(pNodeA5, pNodeA6, pNodeA7); BinaryTreeNode* pNodeB1 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeB2 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeB3 = CreateBinaryTreeNode(); ConnectTreeNodes(pNodeB1, pNodeB2, pNodeB3); Test("Test2", pNodeA1, pNodeB1, false); DestroyTree(pNodeA1);
DestroyTree(pNodeB1);
} // 树中结点只有左子结点,树B是树A的子结构
// 8 8
// / /
// 8 9
// / /
// 9 2
// /
// 2
// /
//
void Test3()
{
BinaryTreeNode* pNodeA1 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeA2 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeA3 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeA4 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeA5 = CreateBinaryTreeNode(); ConnectTreeNodes(pNodeA1, pNodeA2, nullptr);
ConnectTreeNodes(pNodeA2, pNodeA3, nullptr);
ConnectTreeNodes(pNodeA3, pNodeA4, nullptr);
ConnectTreeNodes(pNodeA4, pNodeA5, nullptr); BinaryTreeNode* pNodeB1 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeB2 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeB3 = CreateBinaryTreeNode(); ConnectTreeNodes(pNodeB1, pNodeB2, nullptr);
ConnectTreeNodes(pNodeB2, pNodeB3, nullptr); Test("Test3", pNodeA1, pNodeB1, true); DestroyTree(pNodeA1);
DestroyTree(pNodeB1);
} // 树中结点只有左子结点,树B不是树A的子结构
// 8 8
// / /
// 8 9
// / /
// 9 3
// /
// 2
// /
//
void Test4()
{
BinaryTreeNode* pNodeA1 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeA2 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeA3 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeA4 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeA5 = CreateBinaryTreeNode(); ConnectTreeNodes(pNodeA1, pNodeA2, nullptr);
ConnectTreeNodes(pNodeA2, pNodeA3, nullptr);
ConnectTreeNodes(pNodeA3, pNodeA4, nullptr);
ConnectTreeNodes(pNodeA4, pNodeA5, nullptr); BinaryTreeNode* pNodeB1 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeB2 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeB3 = CreateBinaryTreeNode(); ConnectTreeNodes(pNodeB1, pNodeB2, nullptr);
ConnectTreeNodes(pNodeB2, pNodeB3, nullptr); Test("Test4", pNodeA1, pNodeB1, false); DestroyTree(pNodeA1);
DestroyTree(pNodeB1);
} // 树中结点只有右子结点,树B是树A的子结构
// 8 8
// \ \
// 8 9
// \ \
// 9 2
// \
// 2
// \
// 5
void Test5()
{
BinaryTreeNode* pNodeA1 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeA2 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeA3 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeA4 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeA5 = CreateBinaryTreeNode(); ConnectTreeNodes(pNodeA1, nullptr, pNodeA2);
ConnectTreeNodes(pNodeA2, nullptr, pNodeA3);
ConnectTreeNodes(pNodeA3, nullptr, pNodeA4);
ConnectTreeNodes(pNodeA4, nullptr, pNodeA5); BinaryTreeNode* pNodeB1 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeB2 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeB3 = CreateBinaryTreeNode(); ConnectTreeNodes(pNodeB1, nullptr, pNodeB2);
ConnectTreeNodes(pNodeB2, nullptr, pNodeB3); Test("Test5", pNodeA1, pNodeB1, true); DestroyTree(pNodeA1);
DestroyTree(pNodeB1);
} // 树A中结点只有右子结点,树B不是树A的子结构
// 8 8
// \ \
// 8 9
// \ / \
// 9 3 2
// \
// 2
// \
// 5
void Test6()
{
BinaryTreeNode* pNodeA1 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeA2 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeA3 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeA4 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeA5 = CreateBinaryTreeNode(); ConnectTreeNodes(pNodeA1, nullptr, pNodeA2);
ConnectTreeNodes(pNodeA2, nullptr, pNodeA3);
ConnectTreeNodes(pNodeA3, nullptr, pNodeA4);
ConnectTreeNodes(pNodeA4, nullptr, pNodeA5); BinaryTreeNode* pNodeB1 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeB2 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeB3 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeB4 = CreateBinaryTreeNode(); ConnectTreeNodes(pNodeB1, nullptr, pNodeB2);
ConnectTreeNodes(pNodeB2, pNodeB3, pNodeB4); Test("Test6", pNodeA1, pNodeB1, false); DestroyTree(pNodeA1);
DestroyTree(pNodeB1);
} // 树A为空树
void Test7()
{
BinaryTreeNode* pNodeB1 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeB2 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeB3 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeB4 = CreateBinaryTreeNode(); ConnectTreeNodes(pNodeB1, nullptr, pNodeB2);
ConnectTreeNodes(pNodeB2, pNodeB3, pNodeB4); Test("Test7", nullptr, pNodeB1, false); DestroyTree(pNodeB1);
} // 树B为空树
void Test8()
{
BinaryTreeNode* pNodeA1 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeA2 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeA3 = CreateBinaryTreeNode();
BinaryTreeNode* pNodeA4 = CreateBinaryTreeNode(); ConnectTreeNodes(pNodeA1, nullptr, pNodeA2);
ConnectTreeNodes(pNodeA2, pNodeA3, pNodeA4); Test("Test8", pNodeA1, nullptr, false); DestroyTree(pNodeA1);
} // 树A和树B都为空
void Test9()
{
Test("Test9", nullptr, nullptr, false);
} int main(int argc, char* argv[])
{
Test1();
Test2();
Test3();
Test4();
Test5();
Test6();
Test7();
Test8();
Test9();
system("pause");
return ;
}

《剑指offer》第二十六题(树的子结构)的更多相关文章

  1. 剑指Offer(十七):树的子结构

    剑指Offer(十七):树的子结构 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net/baidu_ ...

  2. 剑指Offer面试题:17.树的子结构

    一.题目:树的子结构 题目:输入两棵二叉树A和B,判断B是不是A的子结构.例如下图中的两棵二叉树,由于A中有一部分子树的结构和B是一样的,因此B是A的子结构. 该二叉树的节点定义如下,这里使用C#语言 ...

  3. 剑指Offer(书):树的子结构

    题目:输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) 分析:关于二叉树大部分适应于递归结构. public boolean HasSubtree(TreeN ...

  4. 【剑指Offer】面试题26. 树的子结构

    题目 输入两棵二叉树A和B,判断B是不是A的子结构.(约定空树不是任意一个树的子结构) B是A的子结构, 即 A中有出现和B相同的结构和节点值. 例如: 给定的树 A:      3     / \ ...

  5. 《剑指offer》面试题26. 树的子结构

    问题描述 输入两棵二叉树A和B,判断B是不是A的子结构.(约定空树不是任意一个树的子结构) B是A的子结构, 即 A中有出现和B相同的结构和节点值. 例如: 给定的树 A:      3     / ...

  6. 《剑指offer》第六题(重要!从尾到头打印链表)

    文件main.cpp // 从尾到头打印链表 // 题目:输入一个链表的头结点,从尾到头反过来打印出每个结点的值. #include <iostream> #include <sta ...

  7. 剑指offer五十六之删除链表中重复的结点

    一.题目 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4->5 处理后 ...

  8. 剑指offer四十六之孩子们的游戏(圆圈中最后剩下的数,约瑟夫环问题)

    一.题目 每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此.HF作为牛客的资深元老,自然也准备了一些小游戏.其中,有个游戏是这样的:首先,让小朋友们围成一个大圈.然后,他随机指 ...

  9. 剑指offer二十六之二叉搜索树与双向链表

    一.题目 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. 二.思路 对二叉搜索树中序遍历的结果即为排序的结果,在中序遍历的过程中,建 ...

  10. 剑指offer三十六之两个链表的第一个公共结点

    一.题目 输入两个链表,找出它们的第一个公共结点. 二.思路 如果存在共同节点的话,那么从该节点,两个链表之后的元素都是相同的.也就是说两个链表从尾部往前到某个点,节点都是一样的.我们可以用两个栈分别 ...

随机推荐

  1. iOS开发--底部按钮和应用图标显示未读消息

    我们要实现的效果如下: 我们使用系统自带的,实际上,代码量很少,在我们要显示的按钮上,打上下面一句代码即可: self.tabBarItem.badgeValue = @"1"; ...

  2. Lintcode: Heapify && Summary: Heap

    Given an integer array, heapify it into a min-heap array. For a heap array A, A[0] is the root of he ...

  3. 终端FQ

    前言我一直以为全局FQ就是所有的都能够自由访问,没想到终端有时候却不行,这里终端一般指的是window的cmd和mac的Terminal.终端一般程序员用的比较多,下载第三方依赖啊,都需要,所以我总结 ...

  4. Verilog篇(三)仿真原理

    首先引入一个例子: `timescale  1ns/100ps module   TB;                                                         ...

  5. Fenwick

    hdu1394 这题说的是给了一个序列计算这个序列的逆序对总共要进行n次 每次都将目前的第一个放到序列的最后一个位置然后 计算一次逆序对 这样我们只需要先求一次逆序对 然后接着每次都用F=F+(n-T ...

  6. Lua安装

    部署环境 lua-5.1.1 VM虚拟机redhat6.5-x64:192.168.1.201 Xshell4 安装 步骤一:安装依赖 yum install -y readline yum inst ...

  7. 拉取远程仓库到本地错误The authenticity of host 'github.com (13.229.188.59)' can't be established.

    1.个人在github上面创建了仓库,通过本地的git拉取远程仓库到本地报错信息如下: 这是因为Git使用SSH连接,而SSH第一次连接需要验证GitHub服务器的Key.确认GitHub的Key的指 ...

  8. svn忽略目录,svn忽略app目录add toignore list,避免每次更新很多app的内容下来导出到本地很麻烦

    svn忽略目录,svn忽略app目录add toignore list,避免每次更新很多app的内容下来导出到本地很麻烦 ------------------------------ 本人微信公众帐号 ...

  9. python3.4学习笔记(十五) 字符串操作(string替换、删除、截取、复制、连接、比较、查找、包含、大小写转换、分割等)

    python3.4学习笔记(十五) 字符串操作(string替换.删除.截取.复制.连接.比较.查找.包含.大小写转换.分割等) python print 不换行(在后面加上,end=''),prin ...

  10. ES6之前模拟Map数据结构的写法

    在ES6之前JavaScript 里面本身没有map对象,但是用JavaScript的Array.Object来模拟实现Map的数据结构. 现在已经有Map对象了,这里记录一下之前的写法 Array方 ...