**
问题详情
**建立二叉链表,统计二叉树中的叶子结点数并输出。
按照完全二叉树的形式输入二叉树的各结点数据(字符),其中虚结点用’@‘表示。输入以’#'结束。
输出叶子结点的个数及具体值。第一行为为叶子结点的数据值,各数据用空格分隔,第二行为叶子结点的个数。
输入示例:
abc@@de#
输出:
b d e
3
解决思路
** 初看此问题有点小懵逼,因为书上一般都是按先中后序建立,但仔细想想可以根据父亲节点与孩子结点编号的关系来建立二叉树。**
- 接收输入,初始化,定义一个指针数组来存储节点,并且数组下标可以显示节点编号
- 如果不是@(虚节点)则给它赋值,并将孩子结点指向空;如果是虚节点,直接将它指向空,最后赋给数组
- 接下来建立亲子关系。如果num=1,即它是第一个节点,所以他不是谁的孩子;如果num大于一,根据亲子编号之间的联系(parent节点编号为i,则它的lchild编号为2i,rchild编号为2*i+1)确定此节点的父亲节点,并让父亲节点指向它(需判断是左孩子还是右孩子)。
- 接收到结束标志‘#’,遍历指针数组,如果此节点存在,并且它的左右孩子均为空,输出值并计数。
完整代码
#include<stdio.h>
#include<stdlib.h>
typedef struct BiTNode
{
char data;
struct BiTNode *lchild,*rchild;
}BiTNode;
int creat(BiTNode * root)
{
int num=0,count=0;
char ch;
BiTNode *s,*tree[100];
while((ch=getchar())!='#')
{
s=(BiTNode*)malloc(sizeof(BiTNode)); //建立一个节点
if(ch!='@') //不是虚节点
{
s->data=ch; //赋值
s->lchild=NULL;
s->rchild=NULL;
num++; //统计节点数并且给结点编号
}
if(ch=='@')
{
s=NULL;//若是虚节点则指向空
num++;
}
tree[num]=s;
if (num==1)//根节点
root=s;
if(num>1)//非根节点
{
if(num%2==0)//左孩子
tree[num/2]->lchild=s;
if(num%2==1)//右孩子
tree[(num-1)/2]->rchild=s;
}
}
for(int i=1;i<=num;i++)//遍历
{
if(tree[i]&&(tree[i]->lchild)==NULL&&(tree[i]->rchild)==NULL)//此节点不为空但其无左右孩子
{
printf("%c ",tree[i]->data);
count++;
}
}
return count;
}
int main()
{
int n;
BiTNode * root;
root=(BiTNode*)malloc(sizeof(BiTNode));
n=creat(root);
printf("\n");
printf("%d",n);
return 0;
}