#include <stdio.h>
#include <stdlib.h>
/* 树的子结构 */
/*先在A树中找到和B树根节点相同的节点
接着,在依次判断*/
typedef struct TreeNode{
int data;
struct TreeNode *LeftNode;
struct TreeNode *RightNode;
}TreeNode;
/*往树中插入数据(常规方法) 创建搜索树 并返回根节点*/
/*涉及到头结点的变换,用** */
TreeNode* insertNode(TreeNode **Node,int data)
{
TreeNode *TepNode = *Node;
if((*Node)==NULL) /*空树,创建树*/
{
(*Node) = (TreeNode *)malloc(sizeof(TreeNode));
(*Node)->data = data;
(*Node)->LeftNode = (*Node)->RightNode = NULL;
}
else /*重点判断放在左子树还是右子树*/
{
while(1)
{
if(data > TepNode->data) /*放右子树*/
{
if(TepNode->RightNode == NULL)
{
TepNode->RightNode = (TreeNode *)malloc(sizeof(TreeNode));
TepNode->RightNode->data = data;
TepNode->RightNode->LeftNode = TepNode->RightNode->RightNode = NULL;
break;
}
TepNode = TepNode->RightNode;
}
else
{
if(TepNode->LeftNode == NULL)
{
TepNode->LeftNode = (TreeNode*)malloc(sizeof(TreeNode));
TepNode->LeftNode->data = data;
TepNode->LeftNode->LeftNode = TepNode->LeftNode->RightNode = NULL;
break;
}
TepNode = TepNode->LeftNode;
}
}
}
return (*Node);
}
/*往树中插入数据(递归方法) 创建搜索树 并返回根节点*/
TreeNode * insertNode1(TreeNode **Node, int data)
{
TreeNode *TepNode = *Node;
if((*Node)==NULL) /*空树,创建树*/
{
(*Node) = (TreeNode *)malloc(sizeof(TreeNode));
(*Node)->data = data;
(*Node)->LeftNode = (*Node)->RightNode = NULL;
}
else
{
if(data > TepNode->data)
insertNode1(&(*Node)->RightNode,data);
else
insertNode1(&(*Node)->LeftNode,data);
}
return (*Node);
}
/*中序遍历一棵树*/
void Mid_Travel(TreeNode *head)
{
if(head)
{
Mid_Travel(head->LeftNode);
printf("%d ",head->data);
Mid_Travel(head->RightNode);
}
}
/*判断根节点的 左右节点 是否相同*/
/*
参数1:A树的根节点
参数2:B树的根节点
返回值: 1 :是
0 : 不是*/
int FindChi(TreeNode *root1,TreeNode *root2)
{
/* 要养成一个习惯,对任何一个树节点进行访问时,一定要提前检测该节点是否为空*/
if(root2 == NULL) /*终止条件1*/
return 1;
else if(root1 == NULL) /*终止条件2*/
return 0;
else if(root1->data != root2->data) /*终止条件3*/
return 0;
/*第一次执行FindChi(root1->LeftNode,root2->LeftNode),如果root1->LeftNode==root2->LeftNode,会再次执行
FindChi(root1->LeftNode,root2->LeftNode);
这次执行完以后,A,B树的左子树都会往下一层...中途如果有不一样,就会返回0,终止;
如果最后能执行到root2 == NULL,说明他们的左子树一直相等
同理,在判断他们的右子树*/
return(FindChi(root1->LeftNode,root2->LeftNode) && FindChi(root1->RightNode,root2->RightNode));
}
/*找根节点相同的节点 找到以后,调用FindChi,判断他们的左右节点是否一样*/
int hassubtree(TreeNode *root1, TreeNode *root2)
{
int result = 0;
if(root1 != NULL && root2 != NULL)
{
if(root1 ->data == root2->data)
/*如果返回1,说明根节点以及根节点的左右子树都一样,下面两个不会执行,退出*/
result = FindChi(root1,root2);
if(!result)
/*如果上面是0,说明跟节点不一样;开始遍历A树左面的每个节点,找和B的根节点一样的节点。找到以后,调用FindChi*/
result = hassubtree(root1->LeftNode, root2);
if(!result)
/*同上*/
result = hassubtree(root1->RightNode, root2);
}
return result;
}
int main(void)
{
TreeNode *Node = NULL;
TreeNode *NodeB = NULL;
TreeNode *root1;
TreeNode *root2;
int data[]={10,2,8,7,5,3,4};
int i = 0,num =7;
for(i=0;i<num;i++)
{
/*往树中插入数据(常规方法) 创建搜索树*/
root1 = insertNode(&Node,data[i]);
/*往树中插入数据(递归方法) 创建搜索树*/
// root = insertNode1(&Node,data[i]);
}
for(i=4;i<7;i++)
{
/*往树中插入数据(常规方法) 创建搜索树*/
root2 = insertNode(&NodeB,data[i]);
}
printf("IS =%d ",hassubtree(root1, root2));
return 0;
}
树的子结构
最新推荐文章于 2024-12-14 13:57:46 发布