#include <stdio.h>
#include <stdlib.h>
#define QUEUE_MAXSIZE 50
typedef char DATA; //定義元素類型
typedef struct ChainTree //定義二叉樹結點類型
{
DATA data; //元素數據
struct ChainTree *left; //左子樹結點指針
struct ChainTree *right; //右子樹結點指針
}ChainBinTree;
ChainBinTree *BinTreeInit(ChainBinTree *node) //初始化二叉樹根結點
{
if(node!=NULL) //若二叉樹根結點不爲空
return node;
else
return NULL;
}
int BinTreeAddNode(ChainBinTree *bt,ChainBinTree *node,int n) //添加數據到二叉樹
//bt爲父結點,node爲子結點,n=1表示添加左子樹,n=2表示添加右子樹
{
if(bt==NULL)
{
printf("父結點不存在,請先設置父結點!\n");
return 0;
}
switch(n)
{
case 1: //添加到左結點
if(bt->left) //左子樹不爲空
{
printf("左子樹結點不爲空!\n");
return 0;
}else
bt->left=node;
break;
case 2://添加到右結點
if( bt->right) //右子樹不爲空
{
printf("右子樹結點不爲空!\n");
return 0;
}else
bt->right=node;
break;
default:
printf("參數錯誤!\n");
return 0;
}
return 1;
}
ChainBinTree *BinTreeLeft(ChainBinTree *bt) //返回左子結點
{
if(bt)
return bt->left;
else
return NULL;
}
ChainBinTree *BinTreeRight(ChainBinTree *bt) //返回右子結點
{
if(bt)
return bt->right;
else
return NULL;
}
int BinTreeIsEmpty(ChainBinTree *bt) //檢查二叉樹是否爲空,爲空則返回1,否則返回0
{
if(bt)
return 0;
else
return 1;
}
int BinTreeDepth(ChainBinTree *bt) //求二叉樹深度
{
int dep1,dep2;
if(bt==NULL)
return 0; //對於空樹,深度爲0
else
{
dep1 = BinTreeDepth(bt->left); //左子樹深度 (遞歸調用)
dep2 = BinTreeDepth(bt->right); //右子樹深度 (遞歸調用)
if(dep1>dep2)
return dep1 + 1;
else
return dep2 + 1;
}
}
ChainBinTree *BinTreeFind(ChainBinTree *bt,DATA data) //在二叉樹中查找值爲data的結點
{
ChainBinTree *p;
if(bt==NULL)
return NULL;
else
{
if(bt->data==data)
return bt;
else{ // 分別向左右子樹遞歸查找
if(p=BinTreeFind(bt->left,data))
return p;
else if(p=BinTreeFind(bt->right, data))
return p;
else
return NULL;
}
}
}
void BinTreeClear(ChainBinTree *bt) // 清空二叉樹,使之變爲一棵空樹
{
if(bt)
{
BinTreeClear(bt->left); //清空左子樹
BinTreeClear(bt->right);//清空右子樹
free(bt);//釋放當前結點所佔內存
bt=NULL;
}
return;
}
void BinTree_DLR(ChainBinTree *bt,void (*oper)(ChainBinTree *p)) //先序遍歷
{
if(bt)//樹不爲空,則執行如下操作
{
oper(bt); //處理結點的數據
BinTree_DLR(bt->left,oper);
BinTree_DLR(bt->right,oper);
}
return;
}
void BinTree_LDR(ChainBinTree *bt,void(*oper)(ChainBinTree *p)) //中序遍歷
{
if(bt)//樹不爲空,則執行如下操作
{
BinTree_LDR(bt->left,oper); //中序遍歷左子樹
oper(bt);//處理結點數據
BinTree_LDR(bt->right,oper); //中序遍歷右子樹/
}
return;
}
void BinTree_LRD(ChainBinTree *bt,void (*oper)(ChainBinTree *p)) //後序遍歷
{
if(bt)
{
BinTree_LRD(bt->left,oper); //後序遍歷左子樹
BinTree_LRD(bt->right,oper); //後序遍歷右子樹/
oper(bt); //處理結點數據
}
return;
}
void oper(ChainBinTree *p) //操作二叉樹結點數據
{
printf("%c ",p->data); //輸出數據
return;
}
void BinTree_Level(ChainBinTree *bt,void (*oper)(ChainBinTree *p)) //按層遍歷
{
ChainBinTree *p;
ChainBinTree *q[QUEUE_MAXSIZE]; //定義一個順序棧
int head=0,tail=0;//隊首、隊尾序號
if(bt)//若隊首指針不爲空
{
tail=(tail+1)%QUEUE_MAXSIZE;//計算循環隊列隊尾序號
q[tail] = bt;//將二叉樹根指針進隊
}
while(head!=tail) //隊列不爲空,進行循環
{
head=(head+1)%QUEUE_MAXSIZE; //計算循環隊列的隊首序號
p=q[head]; //獲取隊首元素
oper(p);//處理隊首元素
if(p->left!=NULL) //若結點存在左子樹,則左子樹指針進隊
{
tail=(tail+1)%QUEUE_MAXSIZE;//計算循環隊列的隊尾序號
q[tail]=p->left;//將左子樹指針進隊
}
if(p->right!=NULL)//若結點存在右孩子,則右孩子結點指針進隊
{
tail=(tail+1)%QUEUE_MAXSIZE;//計算循環隊列的隊尾序號
q[tail]=p->right;//將右子樹指針進隊
}
}
return;
}