1004 Counting Leaves

/数每一层的叶子结点数,我是用的结构数组来储存树的,方法比较笨。层序遍历知道每个结点的层数,这里我使用的是队列存储,堆栈也可以。再遍历数组得到最大层数,通过看结构数组组员有没有层数来判断是否为树的结点,通过结点有没有儿子来判断这个结点是不是叶结点,再用另一个数组来储存每一层叶结点的数目,问题解决/
#include <stdio.h>
#include <stdlib.h>
#define A 101
struct node{//树结点
int Level;//表示在第几层
int K;//表示有几个儿子
int child[A];//指向几个儿子的指针数组,使用前全部置-1,表示没有儿子
};
typedef struct Node LinkNode;
struct Node{//队列结点
int data;
LinkNode *link;
};

typedef struct{//链式队列
LinkNode *front,*rear;
}LinkQueue;

void InitQueue(LinkQueue& Q){//队列的初始化
Q.front=NULL;
Q.rear=NULL;
}

void EnQueue(LinkQueue& Q,int x){//入队,将x插入队尾
LinkNode s=(LinkNode)malloc(sizeof(LinkNode));
s->data=x;
s->link=NULL;
if(Q.rear==NULL){
Q.front=s;
Q.rear=s;
}
else{
Q.rear->link=s;
Q.rear=s;
}
}

int DeQueue(LinkQueue& Q,int& x){//出队,如果队列为空,则返回0,如果不为空,则将队首元素删除,删除数据赋值给x
if(Q.frontNULL)return 0;
LinkNode *s=Q.front;
Q.front=s->link;
x=s->data;
free(s);
if(Q.front
NULL)Q.rear=NULL;
return 1;
}

int main(){
struct node Tree[A];//建立一个node数组, 每个组员都是一个 结构
int N,M,i,j,a,b;
scanf("%d %d",&N,&M);//接收输入信息
if(N){
for(i=0;i<A;i++){
Tree[i].Level=0;//所有结点的等级默认为0,默认没有儿子
Tree[i].K=0;
for(j=0;j<A;j++)
Tree[i].child[j]=-1;
}//指针数组置-1
Tree[1].Level=1;//根结点在第一层
if(M){
for(i=0;i<M;i++){
scanf("%d",&a);//先接收这个父节点
scanf("%d",&b);//知道了他有几个儿子
Tree[a].K=b;
for(j=0;j<Tree[a].K;j++){
scanf("%d",&b);//知道了他每个儿子的坐标
Tree[a].child[j]=b;
}
}
}
//已知根结点的辈分,求其他结点的辈分
LinkQueue Q;
InitQueue(Q);
i=1;
EnQueue(Q,i);
while(Q.front){
DeQueue(Q,i);
if(Tree[i].K>0)
for(j=0;j<Tree[i].K;j++){
EnQueue(Q,Tree[i].child[j]);
Tree[Tree[i].child[j]].Level=Tree[i].Level+1;
}
}
int num[A];
int Lev=1;//num数组用于存放每一层叶结点的数目,Lev表示整个树的层数(高度)
for(i=0;i<A;i++){
if(Lev<Tree[i].Level)Lev=Tree[i].Level;
num[i]=0;
}
for(i=1;i<A;i++)
if(Tree[i].Level&&Tree[i].K==0)//没有儿子并且是则表示 该结点为叶结点
num[Tree[i].Level]++;
printf("%d",num[1]);//先把第一层的叶子结点树print出来,后面就方便统一格式了
for(i=2;i<=Lev;i++){
printf(" %d",num[i]);
}
}
return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值