第4章第1节练习题3 二叉树特殊节点个数统计
来源:互联网 发布:11月经济数据点评 编辑:程序博客网 时间:2024/06/08 10:50
为了方便说明二叉树的递归传值过程,这里首先给出一个基本的二叉树结构。
图中值为NULL的节点实际是不存在的,故与父亲节点之间的连接用灰色的虚线表示。只是为了便于说明,才假设了一个NULL的空节点。
以下图中,黄色的线表明了传值的方向;绿色的数值表明了子节点传到父亲节点时的值,即根据递归公式计算便可。
一.统计二叉树中度为0的节点个数(递归/非递归)
递归方式实现
二叉树中,度为0则表明该节点的左孩子、右孩子均为空,根据二叉树的特性,最容易想到的便是采用递归方式实现该答案。首先列出基本递归公式:
然后可以参考下图
当指针遍历到叶子节点的子节点(NULL节点)时,向父节点返回一个0,又因为该节点是本次遍历需要统计的节点,然后再向父节点返回的时候+1,这样便完成了一次简单的统计,然后再由父节点的父节点对其“汇总”一次,不断的向上递归传值,便完成了叶子节点的统计。
算法描述如下
int CntLfNode_recursive(BiTNode* T){ if(T==NULL){ return 0; } if(T->lchild==NULL&&T->rchild==NULL){ return CntLfNode_recursive(T->lchild)+CntLfNode_recursive(T->rchild)+1; }else{ return CntLfNode_recursive(T->lchild)+CntLfNode_recursive(T->rchild); }}
非递归方式实现
非递归方式的实现就比较容易理解了,只需要使用第4章第3节 二叉树的基本操作(非递归实现)中给到的遍历二叉树的方法,在访问节点时,判断下该节点的度是否为0:如果是0,则对其计数;如果不是,跳过便可。
这里便主体使用层次遍历方式实现,后对叶子节点进行计数,返回该数目。
int CntLfNode_norecursive(BiTNode* T){ BiTNode* p=T; SqQueue Q; InitQueue(&Q); EnQueue(&Q,p); int cnt=0; while(IsEmptyQueue(&Q)!=0){ p=DeQueue(&Q); if(p->lchild==NULL&&p->rchild==NULL){ cnt++; } if(p->lchild!=NULL){ EnQueue(&Q,p->lchild); } if(p->rchild!=NULL){ EnQueue(&Q,p->rchild); } } return cnt;}
二.统计二叉树中度为1的节点个数(递归/非递归)
递归方式实现
统计度为1的节点的递归实现方式与统计度为0的类似,首先列出基本递归公式:
然后可以参考下图
统计度为1的节点的传值过程与度为0的节点的传值过程类似,只是本次统计的是单分支节点而已,然后对此节点向父节点的传值的时候+1便可。
算法描述如下
int CntDONode_recursive(BiTNode* T){ if(T==NULL||(T->lchild==NULL&&T->rchild==NULL)){ return 0; }else if((T->lchild!=NULL&&T->rchild==NULL)||(T->lchild==NULL&&T->rchild!=NULL)){ return CntDONode_recursive(T->lchild)+CntDONode_recursive(T->rchild)+1; }else{ return CntDONode_recursive(T->lchild)+CntDONode_recursive(T->rchild); }}
非递归方式实现
非递归方式的实现方式与统计度为0的节点方式类似,在访问节点时,判断下该节点的度是否为1:如果是1,则对其计数;如果不是,跳过便可。
这里同样主体使用层次遍历方式实现,后对单分支节点进行计数,返回该数目。
int CntDONode_norecursive(BiTNode* T){ BiTNode* p=T; SqQueue Q; InitQueue(&Q); EnQueue(&Q,p); int cnt=0; while(IsEmptyQueue(&Q)!=0){ p=DeQueue(&Q); if((p->lchild!=NULL&&p->rchild==NULL)||(p->lchild==NULL&&p->rchild!=NULL)){ cnt++; } if(p->lchild!=NULL){ EnQueue(&Q,p->lchild); } if(p->rchild!=NULL){ EnQueue(&Q,p->rchild); } } return cnt;}
三.统计二叉树中度为2的节点个数(递归/非递归)
递归方式实现
统计度为2的节点的递归实现方式与统计度为1或度为0的方式类似,首先列出基本递归公式:
然后可以参考下图
与统计度为0和度为1的传值过程类似,只是需要统计的是双分支节点而已,在传值的时候,需要对双分支节点特殊处理,其他一样。
算法描述如下
int CntDTNode_recursive(BiTNode* T){ if(T==NULL){ return 0; } if(T->lchild!=NULL&&T->rchild!=NULL){ return CntDTNode_recursive(T->lchild)+CntDTNode_recursive(T->rchild)+1; }else{ return CntDTNode_recursive(T->lchild)+CntDTNode_recursive(T->rchild); }}
非递归方式实现
与度为0和度为1的节点统计方式类似,在访问节点时,判断下该节点的度是否为2:如果是2,则对其计数;如果不是,跳过便可。
同样主体使用层次遍历方式实现,后对双分支节点进行计数,返回该数目。
int CntDTNode_norecursive(BiTNode* T){ BiTNode* p=T; SqQueue Q; InitQueue(&Q); EnQueue(&Q,p); int cnt=0; while(IsEmptyQueue(&Q)!=0){ p=DeQueue(&Q); if(p->lchild!=NULL&&p->rchild!=NULL){ cnt++; } if(p->lchild!=NULL){ EnQueue(&Q,p->lchild); } if(p->rchild!=NULL){ EnQueue(&Q,p->rchild); } } return cnt;}
具体代码见附件。
附件
//AB#DG###CE##F###include<stdio.h>#include<stdlib.h>#define MaxSize 10typedef char ElemType;typedef struct BiTNode{ ElemType data; struct BiTNode *lchild,*rchild;}BiTNode,*BiTree;typedef struct{ BiTNode* data[MaxSize]; int front, rear;}SqQueue;BiTNode* CreateBiTree(BiTNode*);void InitQueue(SqQueue*);void EnQueue(SqQueue*,BiTNode*);BiTNode* DeQueue(SqQueue*);int IsEmptyQueue(SqQueue*);void PreOrder(BiTNode*);void InOrder(BiTNode*);int CntLfNode_recursive(BiTNode*);int CntLfNode_norecursive(BiTNode*);int CntDONode_recursive(BiTNode*);int CntDONode_norecursive(BiTNode*);int CntDTNode_recursive(BiTNode*);int CntDTNode_norecursive(BiTNode*);int main(int argc, char* argv[]){ BiTNode* T=(BiTNode*)malloc(sizeof(BiTNode)); T=CreateBiTree(T); PreOrder(T);printf("\n"); InOrder(T);printf("\n"); int count_lf; count_lf=CntLfNode_recursive(T); printf("recursive:The count of leaf node is %d\n",count_lf); count_lf=CntLfNode_norecursive(T); printf("non-recursive:The count of leaf node is %d\n",count_lf); int count_do; count_do=CntDONode_recursive(T); printf("recursive:The count of node of degree one is %d\n",count_do); count_do=CntDONode_norecursive(T); printf("non-recursive:The count of degree one node is %d\n",count_do); int count_dt; count_dt=CntDTNode_recursive(T); printf("recursive:The count of degree two node is %d\n",count_dt); count_dt=CntDTNode_norecursive(T); printf("non-recursive:The count of degree two node is %d\n",count_dt); return 0;}//-------------------------------------------------------------------------------------BiTNode* CreateBiTree(BiTNode* T){ ElemType ch; scanf("%c",&ch); if(ch=='#'){ return NULL; } T=(BiTNode*)malloc(sizeof(BiTNode)); T->data=ch; T->lchild=CreateBiTree(T->lchild); T->rchild=CreateBiTree(T->rchild); return T;}//-------------------------------------------------------------------------------------//统计二叉树中度为0的节点个数(递归)int CntLfNode_recursive(BiTNode* T){ if(T==NULL){ return 0; } if(T->lchild==NULL&&T->rchild==NULL){ return CntLfNode_recursive(T->lchild)+CntLfNode_recursive(T->rchild)+1; }else{ return CntLfNode_recursive(T->lchild)+CntLfNode_recursive(T->rchild); }}//统计二叉树中度为0的节点个数(非递归)int CntLfNode_norecursive(BiTNode* T){ BiTNode* p=T; SqQueue Q; InitQueue(&Q); EnQueue(&Q,p); int cnt=0; while(IsEmptyQueue(&Q)!=0){ p=DeQueue(&Q); if(p->lchild==NULL&&p->rchild==NULL){ cnt++; } if(p->lchild!=NULL){ EnQueue(&Q,p->lchild); } if(p->rchild!=NULL){ EnQueue(&Q,p->rchild); } } return cnt;}//-------------------------------------------------------------------------------------//统计二叉树中度为1的节点个数(递归)int CntDONode_recursive(BiTNode* T){ if(T==NULL||(T->lchild==NULL&&T->rchild==NULL)){ return 0; }else if((T->lchild!=NULL&&T->rchild==NULL)||(T->lchild==NULL&&T->rchild!=NULL)){ return CntDONode_recursive(T->lchild)+CntDONode_recursive(T->rchild)+1; }else{ return CntDONode_recursive(T->lchild)+CntDONode_recursive(T->rchild); }}//统计二叉树中度为1的节点个数(非递归)int CntDONode_norecursive(BiTNode* T){ BiTNode* p=T; SqQueue Q; InitQueue(&Q); EnQueue(&Q,p); int cnt=0; while(IsEmptyQueue(&Q)!=0){ p=DeQueue(&Q); if((p->lchild!=NULL&&p->rchild==NULL)||(p->lchild==NULL&&p->rchild!=NULL)){ cnt++; } if(p->lchild!=NULL){ EnQueue(&Q,p->lchild); } if(p->rchild!=NULL){ EnQueue(&Q,p->rchild); } } return cnt;}//-------------------------------------------------------------------------------------//统计二叉树中度为2的节点个数(递归)int CntDTNode_recursive(BiTNode* T){ if(T==NULL){ return 0; } if(T->lchild!=NULL&&T->rchild!=NULL){ return CntDTNode_recursive(T->lchild)+CntDTNode_recursive(T->rchild)+1; }else{ return CntDTNode_recursive(T->lchild)+CntDTNode_recursive(T->rchild); }}//统计二叉树中度为2的节点个数(非递归)int CntDTNode_norecursive(BiTNode* T){ BiTNode* p=T; SqQueue Q; InitQueue(&Q); EnQueue(&Q,p); int cnt=0; while(IsEmptyQueue(&Q)!=0){ p=DeQueue(&Q); if(p->lchild!=NULL&&p->rchild!=NULL){ cnt++; } if(p->lchild!=NULL){ EnQueue(&Q,p->lchild); } if(p->rchild!=NULL){ EnQueue(&Q,p->rchild); } } return cnt;}//-------------------------------------------------------------------------------------//先序遍历void PreOrder(BiTNode* T){ if(T==NULL){ return; } printf("%c",T->data); PreOrder(T->lchild); PreOrder(T->rchild);}//中序遍历void InOrder(BiTNode* T){ if(T==NULL){ return; } InOrder(T->lchild); printf("%c",T->data); InOrder(T->rchild);}//-------------------------------------------------------------------------------------//队列的基本操作void InitQueue(SqQueue* Q){ Q->front=0; Q->rear=0;}void EnQueue(SqQueue* Q, BiTNode* T){ if((Q->rear+1)%MaxSize==Q->front){ return; } Q->data[Q->rear++]=T;}BiTNode* DeQueue(SqQueue* Q){ if(Q->front==Q->rear){ return NULL; } return Q->data[Q->front++];}int IsEmptyQueue(SqQueue* Q){ if(Q->rear==Q->front){ return 0; }else{ return -1; }}
- 第4章第1节练习题3 二叉树特殊节点个数统计
- 第4章第1节练习题7 交换二叉树所有节点左右子树
- 第4章第1节练习题4 二叉树高度和宽度统计
- 第4章第1节练习题6 二叉树叶子节点链接成单链表
- 第4章第1节练习题8 打印指定节点的祖先节点
- 第4章第1节练习题1 二叉树的基本操作(递归实现)
- 第4章第1节练习题15 判断两颗二叉树是否相似
- 第10周 项目3-计算二叉树节点个数
- 第4章第1节练习题5 二叉树查找第k个结点的值
- 第4章第1节练习题10 判断某二叉树是否为完全二叉树
- 求二叉树中叶子节点个数,总的节点个数,第K层的节点个数
- 求二叉树的节点个数、叶子节点个数、第k层的节点个数
- 第4章第1节练习题11 查找最近公共祖先节点
- 第10周 项目3—(1)计算二叉树节点个数
- 第10周—项目3(1)计算二叉树节点个数
- 第4章第1节练习题12 删除以指定节点为根节点的所有子树
- 求二叉树叶子节点的个数+求二叉树第k层的节点个数
- 求二叉树叶子节点的个数/求二叉树第k层的节点个数。
- 传递 context 导致 NullPointerException
- C#访问修饰符
- 定制适用于ARM平台的Ubuntu rootfs(根文件系统)
- MySQL5.7 ERROR 1142 (42000)问题
- view绘制流程
- 第4章第1节练习题3 二叉树特殊节点个数统计
- 解放军上将:日本精神上永远是侏儒 心理永远是弱者
- 数据库事务隔离级别
- Ubuntu下好用的软件推荐
- mysql1607处理
- Android 开源框架ImageLoader完全解析(一)--- 基本介绍及使用
- Linux下静态IP地址的设置及TFTP服务的搭建
- php面向对象及特征
- Git(2)