题目描述
二叉树用数组存储,将二叉树的结点数据依次自上而下,自左至右存储到数组中,一般二叉树与完全二叉树对比,比完全二叉树缺少的结点在数组中用0来表示。
计算二叉树每个结点的平衡因子,并按后序遍历的顺序输出结点的平衡因子。
输入
测试次数t
每组测试数据一行,数组元素个数n,后跟n个字符,二叉树的数组存储。
输出
对每组测试数据,按后序遍历的顺序输出树中结点的平衡因子(测试数据没有空树)
样例输入
2
6 ABC00D
24 ABCD0EF0000H00000000000I
样例输出
B 0
D 0
C 1
A -1
D 0
B 1
I 0
H 1
E 2
F 0
C 2
A -2
思路:
一个结点的平衡因子即为左子树的深度减去右子树的深度
无需建二叉链表,直接依据i结点的孩子为2i+1、2i+2这个下标关系实现递归
用一个le数组表示结点i的左子树的深度,一个ri数组表示右子树的深度
结点i的深度 = max ( 左子树的深度,右子树的深度 )+ 1
依据这个关系,从根结点出发,递归调用求左右子树深度的函数,得到每个结点的左右子树的深度
code:
#include <iostream>
using namespace std;
class Bt{
private:
char *t; //存输入的信息
int n; //长度
int *le; //存左子树深度
int *ri; //存右子树深度
public:
Bt(){};
~Bt(){};
void set_Bt();
void get_balance_factor(int k);
void out_put();
void PostOrder(int k);
};
void Bt::out_put()
{
for(int i=0;i<n;i++)
{
cout<<le[i]<<' '<<ri[i]<<endl;
}
}
void Bt::set_Bt()
{
cin>>n;
t=new char[n];
for(int i=0;i<n;i++)
{
cin>>t[i];
}
le=new int[n];
ri=new int[n];
for(int i=0;i<n;i++)
{
le[i]=-1;
ri[i]=-1;
}
}
void Bt::get_balance_factor(int k) //求结点k的左右孩子的深度
{
int left=k*2+1,right=k*2+2;
if(left>=n) //若左右孩子都不存在,则深度都为0
{
le[k]=0;
ri[k]=0;
}
else
{
if(t[left]=='0') //若左孩子不存在,则深度为0
le[k]=0;
else
{
get_balance_factor(left); //若左孩子存在,则递归求左孩子的左右子树的深度,然后取大的一个+1作为左子树的深度
le[k]=le[left]>ri[left] ? le[left]+1:ri[left]+1;
}
if(right>=n)
ri[k]=0;
else
{
if(t[right]=='0') //若右孩子不存在,则深度为0
ri[k]=0;
else
{
get_balance_factor(right); //若右孩子存在,则递归求右孩子的左右子树的深度,然后取大的一个+1作为右子树的深度
ri[k]=le[right]>ri[right] ? le[right]+1:ri[right]+1;
}
}
}
}
void Bt::PostOrder(int k) //后序输出平衡因子,平衡因子即为左子树深度减右子树深度
{
if(k>=n || t[k]=='0')
return ;
int left=k*2+1,right=k*2+2; //取左右孩子的下标
PostOrder(left); //先输出左孩子的平衡因子
PostOrder(right); //后输出右孩子的平衡因子
cout<<t[k]<<' '<<le[k]-ri[k]<<endl; //最后输出自己的平衡因子
}
int main()
{
int t;
cin>>t;
while(t--)
{
Bt temp;
temp.set_Bt();
temp.get_balance_factor(0);
// temp.out_put();
temp.PostOrder(0);
}
}