《剑指offer》第二十六题(树的子结构)
// 面试题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》第二十六题(树的子结构)的更多相关文章
- 剑指Offer(十七):树的子结构
剑指Offer(十七):树的子结构 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn.net/baidu_ ...
- 剑指Offer面试题:17.树的子结构
一.题目:树的子结构 题目:输入两棵二叉树A和B,判断B是不是A的子结构.例如下图中的两棵二叉树,由于A中有一部分子树的结构和B是一样的,因此B是A的子结构. 该二叉树的节点定义如下,这里使用C#语言 ...
- 剑指Offer(书):树的子结构
题目:输入两棵二叉树A,B,判断B是不是A的子结构.(ps:我们约定空树不是任意一个树的子结构) 分析:关于二叉树大部分适应于递归结构. public boolean HasSubtree(TreeN ...
- 【剑指Offer】面试题26. 树的子结构
题目 输入两棵二叉树A和B,判断B是不是A的子结构.(约定空树不是任意一个树的子结构) B是A的子结构, 即 A中有出现和B相同的结构和节点值. 例如: 给定的树 A: 3 / \ ...
- 《剑指offer》面试题26. 树的子结构
问题描述 输入两棵二叉树A和B,判断B是不是A的子结构.(约定空树不是任意一个树的子结构) B是A的子结构, 即 A中有出现和B相同的结构和节点值. 例如: 给定的树 A: 3 / ...
- 《剑指offer》第六题(重要!从尾到头打印链表)
文件main.cpp // 从尾到头打印链表 // 题目:输入一个链表的头结点,从尾到头反过来打印出每个结点的值. #include <iostream> #include <sta ...
- 剑指offer五十六之删除链表中重复的结点
一.题目 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4->5 处理后 ...
- 剑指offer四十六之孩子们的游戏(圆圈中最后剩下的数,约瑟夫环问题)
一.题目 每年六一儿童节,牛客都会准备一些小礼物去看望孤儿院的小朋友,今年亦是如此.HF作为牛客的资深元老,自然也准备了一些小游戏.其中,有个游戏是这样的:首先,让小朋友们围成一个大圈.然后,他随机指 ...
- 剑指offer二十六之二叉搜索树与双向链表
一.题目 输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表.要求不能创建任何新的结点,只能调整树中结点指针的指向. 二.思路 对二叉搜索树中序遍历的结果即为排序的结果,在中序遍历的过程中,建 ...
- 剑指offer三十六之两个链表的第一个公共结点
一.题目 输入两个链表,找出它们的第一个公共结点. 二.思路 如果存在共同节点的话,那么从该节点,两个链表之后的元素都是相同的.也就是说两个链表从尾部往前到某个点,节点都是一样的.我们可以用两个栈分别 ...
随机推荐
- windows7下docker配置镜像加速
原文地址:https://blog.csdn.net/slibra_L/article/details/77505003 1,本文目的:windows7下docker配置镜像加速,下面是具体操作步骤: ...
- CSS选择器可以用数字开头吗
最好是字母开头,后面用数字可以,直接用数字开头不符合官方规范,虽然浏览器牛逼点也能解析出来,但是最初就不要这么做,坏习惯养成很难改.而且如果团队合作,css的命名都需要有固定的格式,还要有可读性方便他 ...
- virtualBox虚拟机联网
1. 2. 3. 4. 5. 6. 7. 8. 9. 10.
- c#获取指定时区的日期
1.首先将服务器的时间转化为utc时间,然后转换成指定时区的日期 public DateTime GetSpecificZoneNowDate(string zoneName = "Chin ...
- Hibernate—部分
数据持久化的3种方式: merge()方法: 先得到对象的副本:再判断, 如果副本为瞬时状态,则用save()插入 如果副本为游离状态,则用update()更新 最终都是不改变传入对象的状态 save ...
- 查看Tensorflow版本
python -c 'import tensorflow as tf; print(tf.__version__)' # for Python 2 python3 -c 'import tensorf ...
- linux基础命令---bzip2
bzip2 使用Burrows-Wheeler块排序文本压缩算法,将文件进行压缩,压缩比率比一般算法高一些.bzip2要求命令行标志附带一个文件名列表.每个文件都被自己的压缩版本替换,名称为“orig ...
- HTML5 manifest离线缓存技术
干什么用的? 离线缓存为的是第一次请求后,根据manifest文件进行本地缓存,并且在下一次请求后进行展示(若有缓存的话,无需再次进行请求而是直接调用缓存),最根本的感觉是它使得WEB从online可 ...
- java多线程----JUC集合”01之 框架
java集合的架构.主体内容包括Collection集合和Map类:而Collection集合又可以划分为List(队列)和Set(集合). 1. List的实现类主要有: LinkedList, A ...
- OpenCV-跟我一起学数字图像处理之拉普拉斯算子
https://www.cnblogs.com/german-iris/p/4840647.html Laplace算子和Sobel算子一样,属于空间锐化滤波操作.起本质与前面的Spatial Fil ...