求二叉树的宽度有两种方法:
-
用一个指针记录下每层的最右边的结点,当工作指针的值与该指针一致时,说明一层遍历完毕,这样只需记录下每层的结点数,取最大值即可;
-
记录下每个结点所处于的层数,之后只需对层树相同的结点个数进行计数,取其最大值即可
第一种:
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;
}