这是第六天,昨天是周天,做了课程相关实验,收获还是蛮多的,但是过程很曲折,做了很多不必要的工作。
树的最常见的相关算法就是使用递归,因为对于一整个树,其左子树或右子树同样是一个完整的树。
直接或间接的遍历考查,所以要将复杂的题简单化。而且对于树,最最需要小心的是指针的操作,树中有大量的指针操作。在每次使用指针的时候,都要问自己这个指针有没有可能是nullptr,如果有可能的话,那该怎么处理。
画图!画图!画图让思路清晰
接下来,每天四道算法题,不太多也不太少
树(进阶)
树的更复杂的算法,对一些简单遍历或者排序的变形;还有一些特别的树,堆或者红黑树之类的。
题目
树的子结构
输入两棵二叉树A和B,判断B是不是A的子结构。
思路:
1、主要分为两步:①在树A中找到和树B一样的根节点;②判断树A的该“根”节点的子树的结构是否和树B一样
2、第一步在树A中找到和树B的根节点一样的节点,这其实就是树的遍历,可以使用递归的方式
3、第二步判断树A中以R为根节点的子树是不是和树B有相同的结构。同样用递归(所以说不是到达这一步就不用怕段根节点是否相同了,你第一次进来不用判断,但是后面的递归进来之前是没有判断传进来的两个值是否相等的):如果节点R的值和树B的根节点不相同,则以R为根节点的子树和树B肯定不具有相同的结构;
//从树A中找结构为树B的子树
//第二步:在树A中找到与B的子树一样的结构的子树
bool DoesTree1HaveTree2(BinaryTreeNode* rootA, BinaryTreeNode* rootB)
{
//递归结束的条件就是B走到尽头啦
if (rootB == nullptr)
return true;
if (rootA == nullptr) //B还没有结束A就结束了,当然就没有找到一样的子树了
return false;
if (rootA->value != rootB->value)
return false;
//找到一样的根节点了,继续判断它的左子树和右子树
return DoesTree1HaveTree2(rootA->leftNode, rootB->leftNode) && DoesTree1HaveTree2(rootA->rightNode, rootB->rightNode);
}
//第一步:遍历树A,找到与树B的根节点一样的节点
//函数返回的时候,rootA指针指向的内存没有改变,内存里面的东西也没有改变
bool HasSubTree(BinaryTreeNode* rootA, BinaryTreeNode* rootB)
{
bool result = false;
if (rootA != nullptr&&rootB != nullptr) {
if (rootA->value == rootB->value)
result = DoesTree1HaveTree2(rootA, rootB);
//如果没有找到一样的根节点或者找到一样的根节点后它的子树和B不一样就继续往左子树找
if (!result)
result = HasSubTree(rootA-&g