如何判断一棵二叉树树是否为另一棵二叉树的子树

#include <iostream>
#include<queue>
using namespace std;
struct treeNode
{
  int value;
  treeNode* left;
  treeNode* right;
  treeNode* parent;
};//节点结构
void  insert(treeNode **root,int value)
 {
 	treeNode* toBe=new treeNode;
   	toBe->value=value;
	 toBe->parent=NULL;
 	toBe->left=toBe->right=NULL;
 	if(*root==NULL)
 	 {
 	 	 *root=toBe;
 	      return ;
	  }
	treeNode* temp=*root,*p1=NULL;
    while(temp)
       {
	       p1=temp;
       	  if(temp->value>value)
       	    temp=temp->left;
       	  else
       	    temp=temp->right;
       }
    if(p1->value>value)
       p1->left=toBe;
    else
       p1->right=toBe;
    toBe->parent=p1;

 }
//此处是相关的代码
<strong>bool isSameTree(treeNode* root1,treeNode*root2)
{
	if(root2==NULL&&root1==NULL)//两个都等于NULL
	    return true;
	if(root1==NULL||root2==NULL)//只有一个等于NULL
	  return false;
    if(root1->value==root2->value)
    return isSameTree(root1->left,root2->left)&&isSameTree(root1->right,root2->right);
    else
    return false;
}
bool  isSubTree(treeNode* root1,treeNode *root2)
{  bool isSub=false;
    if(root1!=NULL)
   {
     if(root1->value==root2->value)
       {
       	isSub=isSameTree(root1,root2);
       }
       if(!isSub)
	   isSub=isSubTree(root1->left,root2);
	   if(!isSub)
         isSub=isSubTree(root1->right,root2);
   }
return isSub;
}
</strong>
int getHeight(treeNode* root)
{
	if(root==NULL)
	   return 0;
	return getHeight(root->left)>getHeight(root->right)?
	(getHeight(root->left)+1):(getHeight(root->right)+1);

}
void  printByLevel(treeNode *root,int level)
{
  if(root==NULL||level<0)
  return ;
  else if  (level==0)
    {
    	cout<<root->value<<" ";
    	return ;
    }

   else
  {
  	printByLevel(root->left,level-1);
	  printByLevel(root->right,level-1);
  }  

}
int main()
{
    treeNode* root=NULL,*root2=NULL;
    insert(&root,20);
    insert(&root,10);
    insert(&root,30);
    insert(&root,15);
    insert(&root,25);
	insert(&root,35);
    insert(&root,5);
    insert(&root2,10);
    insert(&root2,5);
    insert(&root2,100);
    int high=getHeight(root);
    for(int i=0;i!=high;i++)
      {
      	printByLevel(root,i);
      	   cout<<endl;
		  cout<<"---------"<<endl;
      }
    int high2=getHeight(root2);
    for(int i=0;i!=high2;i++)
      {
      	printByLevel(root2,i);
      	cout<<endl;
		  cout<<"---------"<<endl;
      }
      cout<<isSubTree(root,root2);
}
时间复杂度分析,假设root1的节点数为m.
<span style="font-family: Arial, Helvetica, sans-serif;"> </span><span style="font-family: Arial, Helvetica, sans-serif;">root2的节点数为n.则最坏时间复杂度为O(m*n)</span>
<span style="font-family:Arial, Helvetica, sans-serif;">算法的步骤是这样子的:</span>
<span style="font-family:Arial, Helvetica, sans-serif;">遍历tree1 </span>
找与tree2 根节点相等的节点p2
每次找到p2.就检查以p2为根节点的子树是否与tree2相等,如果相等,就停止遍历
假设tree1 有k个节点值与tree1的根节点相等 则实际最坏时间复杂度为 O(m+k*n)
因而 时间效率还是可以接受的

<span style="font-family: Arial, Helvetica, sans-serif;"> </span>
时间: 2024-09-29 05:53:02

如何判断一棵二叉树树是否为另一棵二叉树的子树的相关文章

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

问题 判断一棵树是否是另一棵树的子树,如图 思路 问题分两步: 找值相同的根结点(遍历解决) 判断两结点是否包含(递归:值.左孩子.右孩子分别相同) 代码 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(

笔试算法题(27):判断单向链表是否有环并找出环入口节点 &amp; 判断两棵二元树是否相等

出题:判断一个单向链表是否有环,如果有环则找到环入口节点: 分析: 第一个问题:使用快慢指针(fast指针一次走两步,slow指针一次走一步,并判断是否到达NULL,如果fast==slow成立,则说明链表有环): 第二个问题:fast与slow相遇时,slow一定还没有走完一圈(反证法可证明):  示意图A为起始点,B为环入口点,C为相遇点,则a1=|AB|表示起始点到换入口的距离,a2=|CB|表示相遇点到环入口点的距离,s1=|AB|+|BC|表示slow指针走的长度,s2表示fast指针

数据结构与算法系列研究五——树、二叉树、三叉树、平衡排序二叉树AVL

树.二叉树.三叉树.平衡排序二叉树AVL 一.树的定义 树是计算机算法最重要的非线性结构.树中每个数据元素至多有一个直接前驱,但可以有多个直接后继.树是一种以分支关系定义的层次结构.    a.树是n(≥0)结点组成的有限集合.{N.沃恩}     (树是n(n≥1)个结点组成的有限集合.{D.E.Knuth})      在任意一棵非空树中:        ⑴有且仅有一个没有前驱的结点----根(root).        ⑵当n>1时,其余结点有且仅有一个直接前驱.         ⑶所有结

创建二叉树 树的深度搜索 广度搜索

树的深度搜索 与树的前序遍历同理 根节点->左孩子->右孩子  树的广度搜索 与树的层次遍历同理 一层一层遍历内容 深度搜索 采用stack的适配器 先进后出原则  而广度搜索采用的queue适配器 先进先出原则 二者正好满足 搜索需求 简要代码如下: #include <iostream> #include <stack> #include <queue> #include <malloc.h> using namespace std; typ

二叉树 树 森林之间的转换

树.森林和二叉树的转换 树转换为二叉树 (1)加线.在所有兄弟结点之间加一条连线. (2)去线.树中的每个结点,只保留它与第一个孩子结点的连线,删除它与其它孩子结点之间的连线. (3)层次调整.以树的根节点为轴心,将整棵树顺时针旋转一定角度,使之结构层次分明.(注意第一个孩子是结点的左孩子,兄弟转换过来的孩子是结点的右孩子) 森林转换为二叉树 (1)把每棵树转换为二叉树. (2)第一棵二叉树不动,从第二棵二叉树开始,依次把后一棵二叉树的根结点作为前一棵二叉树的根结点的右孩子,用线连接起来. 二叉

JS动态构建一棵目录树

JS动态构建一棵目录树 在使用frameset布局的时候,经常会用到目录树,我们可以把一棵树写死,但是更多的情况是,这棵树需要随时被改动,所以我们期望的是他能够被动态的构建. MVC,算是了解一点,那本文就把这棵树根据M-V-C给拆开分解吧. 点击链接demo→ 下面就来看看这棵树是怎么构建的. Module [数据层] var tree = { "id": 0, "a1": { "id": 1, "name": "

复习--二叉树&amp;&amp;树

树是一种很常用的数据结构,日后的学习中会经常碰到运用树的知识. //构造二叉树#include<cstdio> #include<iostream> #include<algorithm> using namespace std; /* 二叉排序树或者是一棵空树,或者是具有下列性质的二叉树: (1)若左子树不空,则左子树上所有结点的值均小于或等于它的根结点的值: (2)若右子树不空,则右子树上所有结点的值均大于或等于它的根结点的值: (3)左.右子树也分别为二叉排序树:

主席树——多棵线段树的集合

主席树: (不要管名字) 我们有的时候,会遇到很多种情况,对于每一种情况,都需要通过线段树的操作实现. 碰巧的是,相邻两种情况下的线段树的差异不大.(总体的差异次数是O(N)级别的,均摊就是O(常数)的了) 显然的是,我们不能对于每种情况都建造一棵线段树.n^n 空间直接MLE无疑. 救命稻草是:发现相邻两种情况下的线段树的差异不大. 所以,我们是否可以让不同的线段树共用同一个节点呢?!?!? 这就是主席树的本质.也是精妙之处所在. 代码实现不是很麻烦. 我一般用传返回值形式,每次返回一个节点编

求一棵普通树的两个结点的最低公共祖先

一棵普通树,树中的结点没有指向父节点的指针,求一棵普通树的两个结点的最低公共祖先. 代码如下,我太懒没有加注释,大家自己看吧! 1 #include <iostream> 2 #include <list> 3 #include <vector> 4 using namespace std; 5 6 struct TreeNode //节点 7 { 8 char m_nValue; 9 vector<TreeNode*> m_vChildren; 10 };