利用先序递归遍历算法创建二叉树并判断该二叉树是否为完全二叉树。完全二叉树只能是同深度的满二叉树缺少最后一层倒数连续个叶子结点。先序递归遍历建立二叉树的方法为:按照先序递归遍历的思想将对二叉树结点的抽象访问具体化为根据接收的数据决定是否产生该结点从而实现创建该二叉树的二叉链表存储结构。约定二叉树结点数据为单个大写英文字符。当接收的数据是字符"#"时表示该结点不需要创建,否则创建该结点。最后判断创建完成的二叉树度是否为完全二叉树。需要注意输入数据序列中的"#"字符和非"#"字符的序列及个数关系,这会最终决定创建的二叉树的形态。
输入
输入为接受键盘输入的由大写英文字符和"#"字符构成的一个字符串(用于创建对应的二叉树)。
输出
对应的二叉树是否为完全二叉树的判断结果。若是输出"Y",否则输出"N"。
样例输入
A##
ABC####
AB##C##
ABCD###EF##G###
A##B##
ABC##D##EG###
样例输出
Y
N
Y
N
Y
Y
如果一棵具有n个结点的深度为k的二叉树,它的每一个结点都与深度为k的
满二叉树中编号为1~n的结点一一对应,这棵二叉树称为完全二叉树。
可以根据公式进行推导,假设n
0
是度为0的结点总数(即
叶子结点
数),n
1
是度为1的结点总数,n
2
是度为2的结点总数,则
①n= n
0
+n
1
+n
2
(其中n为完全二叉树的结点总数);又因为一个度为2的结点会有2个子结点,一个度为1的结点会有1个子结点,除根结点外其他结点都有父结点,所以②n= 1+n
1
+2*n
2
;由①、②两式把n
2
消去得:n= 2*n
0
+n
1
-1,由于完全二叉树中度为1的结点数只有两种可能0或1,由此得到n
0
=n/2 或 n
0
=(n+1)/2。
简便来算,就是 n
0
=n/2,其中n为奇数时(n
1
=0)向上取整;n为偶数时(n
1
=1)。可根据完全二叉树的结点总数计算出叶子结点数。
#include <iostream>
#include <stdlib.h>
using namespace std;
typedef struct tree
{
char date;
tree *left,*right;
}Tree;
int cn=0,cn_1=0;
void add(Tree *&p)
{
char str;
cin>>str;
if(str!='#')
{
p = (Tree*)malloc(sizeof(Tree));
p->date = str;
cn++;//统计总共结点个数
add(p->left);
add(p->right);
}
else
{
p = NULL;
}
}
void find(Tree *&T)
{
if(T!=NULL)
{
if(T->right==NULL&&T->left==NULL)
{
cn_1++;//统计叶子结点个数
}
find(T->left);
find(T->right);
}
}
int main(int argc, const char * argv[]) {
Tree *T;
add(T);
find(T);
if(cn/2==cn_1||(cn+1)/2==cn_1)
{
cout<<"Y";
}
else
{
cout<<"N";
}
return 0;
}