Bootstrap

假设二叉树采用二叉链表存储结构,设计一个算法,求非空二叉树的宽度(即具有结点数最多的那一层的结点个数)

求二叉树的宽度有两种方法:

  1. 用一个指针记录下每层的最右边的结点,当工作指针的值与该指针一致时,说明一层遍历完毕,这样只需记录下每层的结点数,取最大值即可;

  2. 记录下每个结点所处于的层数,之后只需对层树相同的结点个数进行计数,取其最大值即可

第一种:

int width1(BiTree bt)
{//用第一种方法编写如下算法
    if(bt == NULL)
        return 0;
    else
    {
        Queue qu;   qu.front = qu.rear = -1;
        BiTree p;                      //工作指针
        BiTree lastnode = bt;          //用于指向每层最后一个结点
        BiTree newnode = NULL;         //用于查找下一层的最后一个结点
        int max = 1;    int count = 0;  //用于记录每层的结点个数
        qu.data[++qu.rear] = bt;
        while(qu.front != qu.rear)
        {
            p = qu.data[++qu.front];
            if(p->lchild != NULL)
            {
                qu.data[++qu.rear] = p->lchild;
                newnode = p->lchild;
                count++;
            }
            if(p->rchild != NULL)
            {
                qu.data[++qu.rear] = p->rchild;
                newnode = p->rchild;
                count++;
            }
            if(p == lastnode)
            {
                lastnode = newnode;
                if(count>max)
                    max = count;
                count = 0;  //不管count有没有大于max,扫描完一层后都要归零
            }
        }
        return max;
    }
}

第二种:

int width2(BiTree bt, int* depth)
{//用第二种方法编写如下算法(此方法还可以顺带求深度)
    if(bt == NULL)
        return 0;
    else
    {
        Queue qu; qu.front = qu.rear = -1;
        BiTree p;
        qu.data[++qu.rear] = bt;
        qu.level[qu.rear] = 1;
        int k;          //用于记录当前结点的层数;
        while(qu.front != qu.rear)
        {
            p = qu.data[++qu.front];
            k = qu.level[qu.front];
            if(p->lchild != NULL)
            {
                qu.data[++qu.rear] = p->lchild;
                qu.level[qu.rear] = k+1;
            }
            if(p->rchild != NULL)
            {
                qu.data[++qu.rear] = p->rchild;
                qu.level[qu.rear] = k+1;
            }
            
        }//退出循环时所有结点的层数均已存储在qu.level数组中
        
        *depth = k;
        
        //开始扫描qu.level数组
        int max=0;
        int n, i=0;
        k = 1;
        while(i <= qu.front)
        {
            n = 0;
            while(qu.level[i] == k && i <= qu.front)
            {
                n++; i++;
            }
            if(n>max)
                max = n;
            k++;
        }
        
    return max;
    }
}

运行一下瞅瞅

#include <stdio.h>
#include <stdlib.h>
#define maxsize 100

typedef int elemtype;
typedef struct BiTNode {
    elemtype data;
    struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;

typedef struct 
{
    BiTree data[maxsize];
    int level[maxsize];      //用于存储当前结点所在的层
    int front, rear;
}Queue;

BiTree creat_bt(){ //按扩展前序建二叉树;
    BiTree t;   elemtype x;
    scanf("%d",&x);
    if (x==0) t=NULL;
    else 
    { t=(BiTree)malloc(sizeof(BiTNode));
        t->data=x;
        t->lchild=creat_bt();
        t->rchild=creat_bt();
    }
    return t;
}
int width1(BiTree bt)
{//用第一种方法编写如下算法
    if(bt == NULL)
        return 0;
    else
    {
        Queue qu;   qu.front = qu.rear = -1;
        BiTree p;                      //工作指针
        BiTree lastnode = bt;          //用于指向每层最后一个结点
        BiTree newnode = NULL;         //用于查找下一层的最后一个结点
        int max = 1;    int count = 0;  //用于记录每层的结点个数
        qu.data[++qu.rear] = bt;
        while(qu.front != qu.rear)
        {
            p = qu.data[++qu.front];
            if(p->lchild != NULL)
            {
                qu.data[++qu.rear] = p->lchild;
                newnode = p->lchild;
                count++;
            }
            if(p->rchild != NULL)
            {
                qu.data[++qu.rear] = p->rchild;
                newnode = p->rchild;
                count++;
            }
            if(p == lastnode)
            {
                lastnode = newnode;
                if(count>max)
                    max = count;
                count = 0;  //不管count有没有大于max,扫描完一层后都要归零
            }
        }
        return max;
    }
}

int width2(BiTree bt, int* depth)
{//用第二种方法编写如下算法(此方法还可以顺带求深度)
    if(bt == NULL)
        return 0;
    else
    {
        Queue qu; qu.front = qu.rear = -1;
        BiTree p;
        qu.data[++qu.rear] = bt;
        qu.level[qu.rear] = 1;
        int k;          //用于记录当前结点的层数;
        while(qu.front != qu.rear)
        {
            p = qu.data[++qu.front];
            k = qu.level[qu.front];
            if(p->lchild != NULL)
            {
                qu.data[++qu.rear] = p->lchild;
                qu.level[qu.rear] = k+1;
            }
            if(p->rchild != NULL)
            {
                qu.data[++qu.rear] = p->rchild;
                qu.level[qu.rear] = k+1;
            }
            
        }//退出循环时所有结点的层数均已存储在qu.level数组中
        
        *depth = k;
        
        //开始扫描qu.level数组
        int max=0;
        int n, i=0;
        k = 1;
        while(i <= qu.front)
        {
            n = 0;
            while(qu.level[i] == k && i <= qu.front)
            {
                n++; i++;
            }
            if(n>max)
                max = n;
            k++;
        }
        
    return max;
    }
}


int main()
{
    BiTree bt = creat_bt();
    int depth; 
    printf("第一种方法求出的宽度为:%d\n", width1(bt)); 
    printf("第二种方法求出的宽度为:%d\n", width2(bt,&depth));
    printf("顺便求一下深度:%d\n", depth);
    return 0;
}
;