1.非空二叉树的高度
1.1非递归算法实现求解非空二叉树的高度
算法思想:采用层次遍历的算法,设置变量level记录当前结点所在的层数,设置变量last指向当前层的最右的结点,每次层次遍历出队的时候与last指针比较(front与last比较),若两者相等,则层数加1,并让last指向下一层的最右结点,直到遍历完成。 level的值即为二叉树的高度。
int Btdepth(BTNode *T)
{
if(T==NULL)
return 0;
int front,rear; //初始化层次遍历需要的循环队列
front=rear=-1;
BTNode *Que[maxsize];
int last=0,level=0;
BTNode *p;
Que[++rear]=T;
while(front<rear) //队列不空
{
p=Que[++front];
if(p->lchild!=NULL)
Que[++rear]=p->lchild;
if(p->rchild!=NULL)
Que[++rear]=p->rchild;
if(front==last)
{
level++;
last=rear;
}
}
return level;
}
1.2递归算法求解非空二叉树的高度
int getDepth(BTNode *T)
{
int LD,RD;
if(T==NULL)
return 0;
else
{
LD=getDepth(T->lchild);
RD=getDepth(T->rchild);
return (LD>RD?LD:RD)+1;
}
}
2.求解非空二叉树的宽度
算法思想:采用层次遍历的方法求出所有结点的层次,并将所有结点和对应的层次放在一个队列中。然后通过扫描队列求出各层的结点总数,最大的层结点数即为二叉树的宽度。
int BtWidth(BTNode *T)
{
BTNode *p;
int k,max,i,n;
Que Qu;
Qu.front=Qu.rear=-1; //队列为空
Qu.rear++;
Qu.data[Qu.rear]=T; //根节点指针入队
Qu.level[Qu.rear]=1; //根节点的层次为1
while(Qu.front<Qu.rear)
{
Qu.front++; //出队
p=Qu.data[Qu.front]; //出队结点
k=Qu.level[Qu.front]; //出队结点层次
if(p->lchild!=NULL) //左孩子进队
{
Qu.rear++;
Qu.data[Qu.rear]=p->lchild;
Qu.level[Qu.rear]=k+1;
}
if(p->rchild!=NULL) //右孩子入队
{
Qu.rear++;
Qu.data[Qu.rear]=p->rchild;
Qu.level[Qu.rear]=k+1;
}
}//while
max=0;i=0; //max保存同一层最多的结点个数
k=1;
while(i<Qu.rear)
{
n=0;
while(i<Qu.rear&&Qu.level[i]==k)
{
n++;
i++;
}
k=Qu.level[i];
if(n>max)
max=n;
}
return max;
}
3.总的代码实现
#include<stdio.h>
#include<stdlib.h>
#define maxsize 100
typedef struct BTNode
{
struct BTNode *lchild;
struct BTNode *rchild;
int data;
}BTNode;
typedef struct
{
BTNode *data[maxsize]; //保存队列中的结点指针
int level[maxsize]; //保存data中相同下标结点的层次
int front,rear;
}Que;
//二叉排序树的插入
int Insert_BST(BTNode *&T,int key)
{
if(T==NULL)
{
T=(BTNode *)malloc(sizeof(BTNode));
T->lchild=T->rchild=NULL;
T->data=key;
return 1;
}
else
{
if(key==T->data)
return 0;
else if(key<T->data)
return Insert_BST(T->lchild,key);
else
return Insert_BST(T->rchild,key);
}
}
void Visit (BTNode *p)
{
if(p!=NULL)
printf("%d ",p->data);
}
//创建二叉排序树
int Create_BST(BTNode *&T,int arry[],int n)
{
int i=0;
T=NULL;
while(i<n)
{
Insert_BST(T,arry[i]);
i++;
}
}
//递归算法求二叉树的高度
int getDepth(BTNode *T)
{
int LD,RD;
if(T==NULL)
return 0;
else
{
LD=getDepth(T->lchild);
RD=getDepth(T->rchild);
return (LD>RD?LD:RD)+1;
}
}
//非递归求二叉树的高度
/*采用层次遍历的算法,设置变量level记录当前结点所在的层数,设置变量last指向当前层的最右结点,
每次层次遍历出队时和last指针比较,若两者相等,则层数加1,并让last指向下一层的最右结点,直到遍历完成*/
int Btdepth(BTNode *T)
{
if(T==NULL)
return 0;
int front,rear; //初始化层次遍历需要的循环队列
front=rear=-1;
BTNode *Que[maxsize];
int last=0,level=0;
BTNode *p;
Que[++rear]=T;
while(front<rear) //队列不空
{
p=Que[++front];
if(p->lchild!=NULL)
Que[++rear]=p->lchild;
if(p->rchild!=NULL)
Que[++rear]=p->rchild;
if(front==last)
{
level++;
last=rear;
}
}
return level;
}
//求非空二叉树的宽度
int BtWidth(BTNode *T)
{
BTNode *p;
int k,max,i,n;
Que Qu;
Qu.front=Qu.rear=-1; //队列为空
Qu.rear++;
Qu.data[Qu.rear]=T; //根节点指针入队
Qu.level[Qu.rear]=1; //根节点的层次为1
while(Qu.front<Qu.rear)
{
Qu.front++; //出队
p=Qu.data[Qu.front]; //出队结点
k=Qu.level[Qu.front]; //出队结点层次
if(p->lchild!=NULL) //左孩子进队
{
Qu.rear++;
Qu.data[Qu.rear]=p->lchild;
Qu.level[Qu.rear]=k+1;
}
if(p->rchild!=NULL) //右孩子入队
{
Qu.rear++;
Qu.data[Qu.rear]=p->rchild;
Qu.level[Qu.rear]=k+1;
}
}//while
max=0;i=0; //max保存同一层最多的结点个数
k=1;
while(i<Qu.rear)
{
n=0;
while(i<Qu.rear&&Qu.level[i]==k)
{
n++;
i++;
}
k=Qu.level[i];
if(n>max)
max=n;
}
return max;
}
int main()
{
BTNode *T;
int arry[]={40,72,38,35,67,51,90,8,55,21};
Create_BST(T,arry,10);
int depth=getDepth(T);
printf("递归二叉树的高度:%d\n",depth);
int level=Btdepth(T);
printf("非递归二叉树的高度:%d\n",level);
int width=BtWidth(T);
printf("二叉树的最大的宽度:%d\n",width);
}