求二叉树的深度、宽度和叶子结点数

来源:互联网 发布:linux 查看服务器类型 编辑:程序博客网 时间:2024/04/30 04:03

  如果用链表来存储二叉树,那么可以将二叉树定义如下: 

typedef char ElemType;typedef struct node{    ElemType data;     //数据元素    struct node* lchild;  //指向左孩子    struct node* rchild;  //指向右孩子}BTNode;

问题一:二叉树的深度
  二叉树的深度,也叫二叉树的高度,二叉树的深度等于从根结点到叶子结点的最长路径加1。用递归的观点来看,二叉树的深度,等于其最大左右子树的深度加1,而每个左子树(右子树)又可以分解为次左子树+次右子树,它们是深度也是最大子树深度加1。也就是二叉树深度的递归模型f(b)如下:  {f(b)=0,f(b)=Max{f(b>lchid),f(b>rchild)}+1,b=NULL 

对应的递归算法如下:

//求二叉树b的深度int BTNodeDepth(BTNode *b){    int lchilddep,rchilddep;    if(b==NULL)        return 0;    else{        lchilddep=BTNodeDepth(b->lchild);        rchilddep=BTNodeDepth(b->rchild);        return (lchilddep>rchilddep)?(lchilddep+1):(rchilddep+1);    }}

问题二:二叉树的宽度
  二叉树的宽度:具有结点数最多的那一层的结点个数。
  采用分层遍历的方法求出所有结点的层编号,然后,求出各层的结点总数,通过比较找出层结点数最多的值。对应的算法如下:  

//求二叉树b的宽度int BTWidth(BTNode *b){    struct{        int lno;        //结点的层次编号        BTNode *p;      //结点指针    }Qu[MaxSize];      //定义顺序非循环队列    int front,rear;    int lnum,max,i,n;    front=rear=0;      //置队列为空    if (b!=NULL)    {        rear++;        Qu[rear].p=b;      //根结点指针入队        Qu[rear].lno=1;    //根结点的层次编号为1        while (rear!=front)  //队列不为空        {            front++;            b=Qu[front].p;    //队头出队            lnum=Qu[front].lno;            if (b->lchild!=NULL)  //左孩子入队            {                rear++;                Qu[rear].p=b->lchild;                Qu[rear].lno=lnum+1;            }            if (b->rchild!=NULL)  //右孩子入队            {                rear++;                Qu[rear].p=b->rchild;                Qu[rear].lno=lnum+1;            }        }        max=0; lnum=1; i=1;        while (i<=rear)        {            n=0;            while (i<=rear && Qu[i].lno==lnum)            {                n++; i++;            }            lnum=Qu[i].lno;            if(n>max) max=n;        }        return max;    }    else        return 0;}

问题三:二叉树b的叶子结点个数
  当b为空树时,叶子结点数为0;
  当b的左子树和右子树都为空,b只有一个结点时,叶子结点数为1;
  当b的左子树或右子树不为空时,叶子结点数=左子树叶子结点数+右子树叶子结点数。
  即递归模型为:

f(b)=0,f(b)=1,f(b)=f(b>lchild)+f(b>rchild),b=NULLb->lchild==NULLb->rchild==NULL

对应的递归算法如下:

//求二叉树b的叶子结点个数int LeafNodes(BTNode *b){    int num1,num2;    if(b==NULL)        return 0;    else if(b->lchild==NULL && b->rchild==NULL)        return 1;    else{        num1=LeafNodes(b->lchild);        num2=LeafNodes(b->rchild);        return (num1+num2);    }}

完整代码如下:

//BinaryTreeBase.h#include <stdio.h>#include <malloc.h>#define MaxSize 100typedef char ElemType;typedef struct node{    ElemType data;     //数据元素    struct node* lchild;  //指向左孩子    struct node* rchild;  //指向右孩子}BTNode;//由str串创建二叉链void CreateBTNode(BTNode *&b,char *str){    BTNode *St[MaxSize],*p=NULL;    int top=-1,k,j=0;    char ch;    b=NULL;    ch=str[j];    while (ch!='\0')    {        switch(ch){        case '(': top++; St[top]=p; k=1; break;        case ')': top--; break;        case ',': k=2; break;        default: p=(BTNode *)malloc(sizeof(BTNode));            p->data=ch; p->lchild=p->rchild=NULL;            if(b==NULL)                b=p;            else{                switch(k){                case 1: St[top]->lchild=p; break;                case 2: St[top]->rchild=p; break;                }            }        }        j++;        ch=str[j];    }}//返回data域为x的结点指针BTNode *FindNode(BTNode *b,ElemType x){    BTNode *p;    if(b==NULL)        return NULL;    else if(b->data==x)        return b;    else{        p=FindNode(b->lchild,x);        if(p!=NULL)            return p;        else            return FindNode(b->rchild,x);    }}BTNode *LchildNode(BTNode *p){    return p->lchild;}BTNode *RchildNode(BTNode *p){    return p->rchild;}//求二叉树b的深度int BTNodeDepth(BTNode *b){    int lchilddep,rchilddep;    if(b==NULL)        return 0;    else{        lchilddep=BTNodeDepth(b->lchild);        rchilddep=BTNodeDepth(b->rchild);        return (lchilddep>rchilddep)?(lchilddep+1):(rchilddep+1);    }}//用括号表示法输出二叉树void DispBTNode(BTNode *b){    if (b!=NULL)    {        printf("%c",b->data);        if (b->lchild!=NULL || b->rchild!=NULL)        {            printf("(");            DispBTNode(b->lchild);            if(b->rchild!=NULL) printf(",");            DispBTNode(b->rchild);            printf(")");        }    }}void printBTN(BTNode *b,int w){    int i;    if (b!=NULL)    {        printBTN(b->rchild,w+5);        for(i=1;i<w;i++)            printf(" ");        printf("%c\n",b->data);        printBTN(b->lchild,w+5);    }}//求二叉树b的宽度int BTWidth(BTNode *b){    struct{        int lno;        //结点的层次编号        BTNode *p;      //结点指针    }Qu[MaxSize];      //定义顺序非循环队列    int front,rear;    int lnum,max,i,n;    front=rear=0;      //置队列为空    if (b!=NULL)    {        rear++;        Qu[rear].p=b;      //根结点指针入队        Qu[rear].lno=1;    //根结点的层次编号为1        while (rear!=front)  //队列不为空        {            front++;            b=Qu[front].p;    //队头出队            lnum=Qu[front].lno;            if (b->lchild!=NULL)  //左孩子入队            {                rear++;                Qu[rear].p=b->lchild;                Qu[rear].lno=lnum+1;            }            if (b->rchild!=NULL)  //右孩子入队            {                rear++;                Qu[rear].p=b->rchild;                Qu[rear].lno=lnum+1;            }        }        max=0; lnum=1; i=1;        while (i<=rear)        {            n=0;            while (i<=rear && Qu[i].lno==lnum)            {                n++; i++;            }            lnum=Qu[i].lno;            if(n>max) max=n;        }        return max;    }    else        return 0;}//求二叉树b的结点个数int Nodes(BTNode *b){    int num1,num2;    if(b==NULL)        return 0;    else if(b->lchild==NULL && b->rchild==NULL)        return 1;    else{        num1=Nodes(b->lchild);        num2=Nodes(b->rchild);        return (num1+num2+1);    }}//求二叉树b的叶子结点个数int LeafNodes(BTNode *b){    int num1,num2;    if(b==NULL)        return 0;    else if(b->lchild==NULL && b->rchild==NULL)        return 1;    else{        num1=LeafNodes(b->lchild);        num2=LeafNodes(b->rchild);        return (num1+num2);    }}//主函数.cpp#include "BinaryTreeBase.h"#include <stdio.h>void main(){    BTNode* bt;    char str[20]="A(B(D(,G)),C(E,F))";    CreateBTNode(bt,str);    printf("二叉树的括号表示法:");    DispBTNode(bt);    printf("\n");    printf("横向打印二叉树:\n");    printBTN(bt,10);    printf("\n");    int num=0,leafNum=0,deepth=0,width=0;    num=Nodes(bt);    leafNum=LeafNodes(bt);    deepth=BTNodeDepth(bt);    width=BTWidth(bt);    printf("二叉树的结点数: %d\n",num);    printf("二叉树的叶子结点数: %d\n",leafNum);    printf("二叉树的深度: %d\n",deepth);    printf("二叉树的宽度: %d\n",width);}

效果如下:

这里写图片描述

图(1) 用括号表示法,创建二叉树,并求它的深度、宽度和叶子结点数

1 0
原创粉丝点击