算法思想
統計二叉樹中葉子結點的個數和度爲1、度爲2的結點個數,因此可以參照二叉樹三種遍歷算法(先序、中序、後序)中的任何一種去完成,只需將訪問操作具體變爲判斷是否爲葉子結點和度爲1、度爲2的結點及統計操作即可。
#include <stdio.h>
#include <stdlib.h>
int LeafCount=0;
int Degree1Count=0;
int Degree2Count=0;
typedef char DataType; //二叉鏈表結點的數據類型
typedef struct Node //定義二叉樹的二叉鏈表結點結構
{
DataType data;
struct Node *LChild; //左子樹
struct Node *RChild; //右子樹
}BiTNode,*BiTree;
void CreateBiTree(BiTree *bt); //創建二叉鏈表函數
void PreOrder(BiTree root); //先序遍歷二叉樹
void InOrder(BiTree root); //中序遍歷二叉樹
void PostOrder(BiTree root); //後序遍歷二叉樹
void Leaf(BiTree root); //統計葉子結點數目
void Degree1(BiTree root); //統計度爲1的結點數目
void Degree2(BiTree root); //統計度爲2的結點數目
int main()
{
BiTree bt;
int choice;
while(true)
{ //二叉樹操作選擇菜單
printf("*****************Please enter your choice*****************\n\n");
printf(" choice 1:創建二叉樹\n");
printf(" choice 2:先序遍歷二叉樹\n");
printf(" choice 3:中序遍歷二叉樹\n");
printf(" choice 4:後序遍歷二叉樹\n");
printf(" choice 5:打印葉子結點數目\n");
printf(" choice 6:打印度爲1的結點數目\n");
printf(" choice 7:打印度爲2的結點數目\n");
printf(" choice 0:退出\n\n");
scanf("%d",&choice);
switch(choice)
{
case 1: CreateBiTree(&bt);
break;
case 2: PreOrder(bt);
printf("\n");
break;
case 3: InOrder(bt);
printf("\n");
break;
case 4: PostOrder(bt);
printf("\n");
break;
case 5: Leaf(bt);
printf("該二叉樹葉子結點的數目爲:%d\n",LeafCount);
break;
case 6: Degree1(bt);
printf("該二叉樹度爲1的結點數目爲:%d\n",Degree1Count);
break;
case 7: Degree2(bt);
printf("該二叉樹度爲2的結點數目爲:%d\n",Degree2Count);
break;
case 0: exit(0);
break;
default:
printf("ERROR!!\n");
exit(0);
break;
}
}
return 0;
}
void CreateBiTree(BiTree *bt)
{
char ch;
printf("Please enter data:");
getchar();
ch = getchar();
if(ch == '.') //讀入的數據是'.'則將當前樹根置爲空
{
*bt = NULL;
}
else //讀入正常數據,爲當前樹根分配地址空間
{
*bt = (BiTree)malloc(sizeof(BiTNode));
(*bt)->data = ch;
CreateBiTree(&((*bt)->LChild)); //遞歸調用CreateBiTree()函數,處理左子樹
CreateBiTree(&((*bt)->RChild)); //遞歸調用CreateBiTree()函數,處理右子樹
}
}
void PreOrder(BiTree root) //先序遍歷二叉樹,root爲指向二叉樹根結點的指針
{
if(root!=NULL)
{
printf("%c ",root->data); //訪問根結點
PreOrder(root->LChild); //先序遍歷左子樹
PreOrder(root->RChild); //先序遍歷右子樹
}
}
void InOrder(BiTree root) //中序遍歷二叉樹,root爲指向二叉樹根結點的指針
{
if(root!=NULL)
{
InOrder(root->LChild); //中序遍歷左子樹
printf("%c ",root->data); //訪問根結點
InOrder(root->RChild); //中序遍歷右子樹
}
}
void PostOrder(BiTree root) //中序遍歷二叉樹,root爲指向二叉樹根結點的指針
{
if(root!=NULL)
{
PostOrder(root->LChild); //後序遍歷左子樹
PostOrder(root->RChild); //後序遍歷右子樹
printf("%c ",root->data); //訪問根結點
}
}
void Leaf(BiTree root)
{
if(root!=NULL)
{
Leaf(root->LChild);
Leaf(root->RChild);
if(root->LChild==NULL && root->RChild==NULL)
{
LeafCount++; //統計葉子結點數目
}
}
}
void Degree1(BiTree root)
{
if(root!=NULL)
{
Degree1(root->LChild);
Degree1(root->RChild);
if((root->LChild==NULL && root->RChild!=NULL)||(root->LChild!=NULL && root->RChild==NULL))
{
Degree1Count++; //統計度爲1的結點數目
}
}
}
void Degree2(BiTree root)
{
if(root!=NULL)
{
Degree2(root->LChild);
Degree2(root->RChild);
if(root->LChild!=NULL && root->RChild!=NULL)
{
Degree2Count++; //統計度爲2的結點數目
}
}
}