二叉树遍历的应用
二叉树的遍历有四个应用:
- 求二叉树深度
- 求二叉树所有节点
- 求二叉树的叶子结点
- 复制二叉树
二叉树的深度
深度:根节点到叶子节点的最长路径(边的个数)
求二叉树的深度->左子树的深度与右子数的深度,最大的哪个
int calculate_depth(pBT pB) //计算深度
{
int m, n;
if(pB==NULL)
{
return 0;
}
else
{
m = calculate_depth(pB->left); //计算左子树深度
n = calculate_depth(pB->right); //计算右子树深度
if(m>=n) //比较哪个深度更大,返回大的深度
{
return m + 1;
}
return n + 1;
}
}
求二叉树的所有节点
二叉树的所有节点:根节点+左子树的结点+右子树的结点
int calculate_sum(pBT pB)
{
int m,n;
if(pB==NULL)
{
return 0;
}else
{
m = calculate_sum(pB->left); //记录左子树的结点数
n = calculate_sum(pB->right); //记录右子树的结点数
return m + n + 1; //还要加上根节点
}
}
求二叉树的叶子结点
叶子节点:左右孩子指针为NULL
int calculate_sumleaf(pBT pB)
{
int m, n;
if(pB==NULL) //如果为空,证明是空树,叶子节点为0
{
return 0;
}
if(pB->left==NULL&&pB->right==NULL) //左指针和右指针为NULL,说明是叶子节点
{
return 1;
}
else
{
m = calculate_sumleaf(pB->left); //计算左子树叶子结点
n = calculate_sumleaf(pB->right); //计算右子树叶子节点
return m + n; //左子树和右子数叶子节点相加
}
}
复制二叉树
采用的是前序遍历的方法来复制二叉树,先复制根节点再复制左子树再复制右子数
pBT copy_tree(pBT pB)
{
pBT pB1;
if(pB==NULL)
{
pB1 = NULL;
return ;
}else
{
pB1 = (pBT)malloc(sizeof(BT));
pB1->data = pB->data; //先复制根节点
pB1->left = copy_tree(pB->left); //再复制左子树
pB1->right = copy_tree(pB->right); //然后复制右子树
}
return pB1;
}
完整代码
#include <stdio.h>
#include <windows.h>
#include <malloc.h>
#include <stdbool.h>
/*二叉树的函数和数据结构*/
typedef struct binary_tree
{
int data;
struct binary_tree *left, *right;
} BT, *pBT;
void create_tree(pBT *);
int calculate_depth(pBT);
int calculate_sum(pBT);
pBT copy_tree(pBT);
void Pretraverse_tree(pBT);
int main()
{
pBT pB;
pBT pB1;
printf("please input the information(AB#C##D##):");
create_tree(&pB);
printf("the depth of the tree:%d\n", calculate_depth(pB));
printf("the sum of the tree:%d\n", calculate_sum(pB));
printf("the sum of the tree leaf:%d\n", calculate_sumleaf(pB));
pB1=copy_tree(pB);
Pretraverse_tree(pB1);
}
void create_tree(pBT *T) //建立一个二叉树
{
char c;
scanf("%c", &c);
if (c == '#')
{
*T = NULL;
}
else
{
(*T) = (pBT)malloc(sizeof(BT));
(*T)->data = c;
create_tree(&(*T)->left);
create_tree(&(*T)->right);
}
}
void Pretraverse_tree(pBT pB) //二叉树的前序遍历
{
if(pB==NULL)
{
return;
}
else
{
printf("%c", pB->data);
Pretraverse_tree(pB->left);
Pretraverse_tree(pB->right);
}
}
int calculate_depth(pBT pB) //计算深度
{
int m, n;
if(pB==NULL)
{
return 0;
}
else
{
m = calculate_depth(pB->left); //计算左子树深度
n = calculate_depth(pB->right); //计算右子树深度
if(m>=n) //比较哪个深度更大,返回大的深度
{
return m + 1;
}
return n + 1;
}
}
int calculate_sum(pBT pB)
{
int m,n;
if(pB==NULL)
{
return 0;
}else
{
m = calculate_sum(pB->left); //记录左子树的结点数
n = calculate_sum(pB->right); //记录右子树的结点数
return m + n + 1;
}
}
int calculate_sumleaf(pBT pB)
{
int m, n;
if(pB==NULL) //如果为空,证明是空树,叶子节点为0
{
return 0;
}
if(pB->left==NULL&&pB->right==NULL) //左指针和右指针为NULL,说明是叶子节点
{
return 1;
}
else
{
m = calculate_sumleaf(pB->left); //计算左子树叶子结点
n = calculate_sumleaf(pB->right); //计算右子树叶子节点
return m + n; //左子树和右子数叶子节点相加
}
}
pBT copy_tree(pBT pB)
{
pBT pB1;
if(pB==NULL)
{
pB1 = NULL;
return ;
}else
{
pB1 = (pBT)malloc(sizeof(BT));
pB1->data = pB->data; //先复制根节点
pB1->left = copy_tree(pB->left); //再复制左子树
pB1->right = copy_tree(pB->right); //然后复制右子树
}
return pB1;
}
遍历的方法是前序遍历.所以复制输出的是前序遍历的顺序(即输入顺序)