判断一颗二叉树是不是另一棵二叉树的子结构

判断一颗二叉树是不是另一棵二叉树的子结构


1、题目描述:

     如何判断一个二叉树是否是另一个的子结构?
     比如:

        2
      /   \
     9    8
    / \    /
   2  3  5
  /

6

   有个子结构是
   9
  / \
2  3

2、 分析问题:

    有关二叉树的算法问题,一般都可以通过递归来解决。那么写成一个正确的递归程序,首先一定要分析正确递归结束的条件。

拿这道题来讲,什么时候递归结束。

<1>第二个二叉树root2为空时,说明root2是第一棵二叉树的root1的子结构,返回true。

<2>当root1为空时,此时root2还没为空,说明root2不是root1的子结构,返回false。

<3>递归下面有两种思路:

    方法一:现在root1中找结点值与root2的值相等的结点,如果找到就判断root2是不是这个结点开头的子结构。所以,首先IsSubTree()判断。

    方法二:就是直接判断,相同就递归判断root2左右子树是不是也是相应的子结构。如果值不相同,就分别递归到root1的左右子树寻找。尤其要注意最后两句递归的逻辑判断。

3、代码:

方法一:

//判断root2是不是root1开头的子结构

boolIsSubTree(BiTreeNode *root1,BiTreeNode *root2)

{

       //先判断root2

       if(root2==NULL)

              return true;

       if(root1==NULL)

              return false;   

       if(root1->data!=root2->data)

              return false;

       returnIsSubTree(root1->LC,root2->LC) &&IsSubTree(root1->RC,root2->RC);

}

//递归查找以root1为节点的树中,是否有和root2相同的值,如果有,则调用IsSubTree(root1, root2);

boolCheckIfSubTree(BiTreeNode *root1,BiTreeNode *root2)

{

       if(root1==NULL)

              return false;

       bool result=false;

       if(root1->data==root2->data)

              result=IsSubTree(root1,root2);

       if(result==false)

              result=CheckIfSubTree(root1->LC,root2);

       if(result==false)

              result=CheckIfSubTree(root1->RC,root2);

       return result;

}

方法二:

//一次递归完成

boolCheckIfSubTree2(BiTreeNode *root1,BiTreeNode *root2)

{

       if(root2==NULL)

              return true;

       if(root1==NULL)

              return false;

       if(root1->data==root2->data)

              returnCheckIfSubTree2(root1->LC,root2->LC) &&CheckIfSubTree2(root1->RC,root2->RC);

       else

              returnCheckIfSubTree2(root1->LC,root2) || CheckIfSubTree2(root1->RC,root2);

}

4、附先序生成二叉树的代码

struct BiTreeNode
{
struct BiTreeNode* LC;
struct BiTreeNode* RC;
int data;
};


void CreateBiTree(BiTreeNode* &root)
{
int ch;
cin>>ch;
if(ch==0)
{
root=NULL;
}
else
{
root=(BiTreeNode*)malloc(sizeof(BiTreeNode));
if(root==NULL)
exit(1);
root->data=ch;
//cout<<"--"<<root->data<<endl;
CreateBiTree(root->LC);
CreateBiTree(root->RC);
}
}

5、小结

一定要好好的体会递归,尤其是递归结束的情况。这是解大多数递归问题的关键。

本代码已在VC++6.0调试通过,欢迎大家提出问题。
在C语言中,判断一棵二叉树是否是完全二叉树,可以采用深度优先搜索(DFS)的方式逐层检查。一个二叉树是完全二叉树,如果每个层级都是满的,除了最后一层外,其余各层都尽可能地填满,且最后一层的所有节点都在最左边。 下面是一个简单的算法步骤: 1. 定义一个函数`isCompleteTree(root)`,该函数接收二叉树的根节点作为输入。 2. 对于每一层,计算当前层的实际节点数和最大节点数(如果是满的,应该是2^(layer+1)-1),两者相等则说明到这一层为止是完全二叉树。 3. 如果到达了最后一层,遍历剩余的节点,如果它们不是左孩子,那么这棵树就不是完全二叉树。 4. 递归地对左右子树进行同样的检查。 伪代码如下: ```c int isCompleteTree(Node* root) { if (root == NULL) return 1; // 空树视为完全二叉树 int layer = 0; int maxNodesInLayer = 1 << (layer + 1); // 计算当前层的最大节点数 Node* current = root; while (current != NULL) { ++layer; // 检查当前层是否有空位 if (current->left != NULL && current->right != NULL) { maxNodesInLayer <<= 1; } // 如果当前层的节点数小于最大节点数,不是完全二叉树 if (current->numChildren < maxNodesInLayer) break; current = current->left ? current->right : NULL; } // 检查剩余的节点是否全在左边 if (current != NULL) return 0; return isCompleteTree(root->left) && isCompleteTree(root->right); } ``` 其中,`Node`结构包含指向左右孩子的指针和一个表示子节点数量的变量`numChildren`。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值