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);
}