#include
#include
#include
#include
#include
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define MAXSIZE 24/*存储空间初始量分配*/
#define LONG sizeof(BiNode)
#define TREE "ABDH#K###E##CFI###G#J##"//需要创建的树
typedef int Status;//Status为函数变量类型返回值如OK等
typedef char TElemType;
typedef char String[25];//0号单元存放字符串长度
typedef struct BiNode//定义二叉树
{
TElemType data;
struct BiNode *lchild,*rchild;
}BiNode,*BiTree;
typedef struct queue
{
BiTree data[MAXSIZE];//定义一个BiTree型指针数组存放二叉树节点
int front,rear;
}LinkQueue;
Status CreateTree(BiTree *T);
void Destory(BiTree T);
void PreOrderTraverse(BiTree T);//先序遍历
void InOrderTraverse(BiTree T);//中序遍历
void PostOrderTraverse(BiTree T);//后序遍历
void GroundOrderTraverse(BiTree T);//层级遍历
int BiTreeDepth(BiTree T);//求深度
int TreeLeaf(BiTree T);//求叶子节点数
Status StrAssign(String T,char *chars);
Status CreateQueue(LinkQueue*S);
Status EnQueue(LinkQueue*S,BiTree T);
Status Deueue(LinkQueue*S,BiTree temp);
String str;
int zb = 1;
int main()
{
int i = 0;
char key;
BiTree T;
StrAssign(str,TREE);
while('i' != key)
{
printf("选择要使用的功能:\n");
printf("a:创建二叉树b:销毁二叉树c:求二叉树深度d:求叶子节点数e:先序遍历f:中序遍历g:后序遍历h:层次遍历i:退出\n");
scanf("%c",&key);
getchar();
switch(key)
{
case 'a':CreateTree(&T);break;
case'b':Destory(T);break;
case 'c':i =BiTreeDepth(T);printf("%d\n",i);break;
case 'd':i =TreeLeaf(T);printf("%d\n",i);break;
case'e':PreOrderTraverse(T);break;
case'f':InOrderTraverse(T);break;
case 'g':PostOrderTraverse(T);break;
case'h':GroundOrderTraverse(T);break;
case'i':printf("beybey\n");break;
default :printf("输入错误请从新输入\n");
}
}
return 0;
}
Status StrAssign(String T,char *chars)
{
int i;
if(strlen(chars) > MAXSIZE)
return ERROR;
T[0] = strlen(chars);//T[0]存放数组长度
for(i = 1;i <= T[0]; i++)
T[i] = *(chars + i - 1);//将chars中字符赋给从T[1]开始的数组
return OK;
}
Status CreateTree(BiTree*T)
{
TElemType ch;
ch = str[zb++];
if(ch == '#')//判出条件
return 0;
*T = (BiTree)malloc(LONG);
if(!*T)
return ERROR;
(*T)->data = ch;
CreateTree(&((*T)->lchild));
CreateTree(&((*T)->rchild));//递归调用左右子树
return OK;
}
void Destory(BiTree T)
{
if(T)
{
if(T->lchild)
Destory(T->lchild);
if(T->rchild)
Destory(T->rchild);
free(T);//递归调用左右子树释放空间
T = NULL;
}
}
int BiTreeDepth(BiTree T)
{
int i,j;
if(!T)
return 0;//如果根为空返回深度为1
if(T->lchild)
i =BiTreeDepth(T->lchild);
else
i = 0;
if(T->rchild)
j =BiTreeDepth(T->rchild);
else
j = 0;
return i>j?i+1:j+1;//递归分别计算根节点向下左右子树深度并返回大的那个值+1
}
void PreOrderTraverse(BiTree T)//先序遍历
{
if(NULL == T)
return;
printf("%c",T->data);
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
void InOrderTraverse(BiTree T)//中序遍历
{
if(NULL == T)
return;
InOrderTraverse(T->lchild);
printf("%c",T->data);
InOrderTraverse(T->rchild);
}
void PostOrderTraverse(BiTree T)//后序遍历
{
if(NULL == T)
return;
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
printf("%c",T->data);
}
Status CreatQueue(LinkQueue *S)
{
S->front = S->rear = 0;
return OK;
}
Status EnQueue(LinkQueue *S,BiTree T)
{
if((S->rear + 1)%MAXSIZE ==S->front)
{
return ERROR;
printf("队列满\n");
}
S->data[S->rear] = T;
S->rear = (S->rear +1)%MAXSIZE;//rear向后移一位,当rear到数组尾回到0
return OK;
}
Status DeQueue(LinkQueue*S,BiTree*temp)
{
if(S->rear == S->front)
{
printf("队列空\n");
return ERROR;
}
*temp = S->data[S->front];//注意指针指向
S->front = (S->front +1)%MAXSIZE;//循环队列出队列,当front到数组尾回到0
return OK;
}
void GroundOrderTraverse(BiTree T)
{
int count = 1;
LinkQueue S;
BiTree temp = T;
if(!temp)
return;
CreatQueue(&S);
EnQueue(&S,temp);
do
{
if(DeQueue(&S,&temp))
{
printf("%c",temp->data);//取出节点
count--;
}
if(temp->lchild)
{
EnQueue(&S,temp->lchild);
count++;
}
if(temp->rchild)
{
EnQueue(&S,temp->rchild);//将左右儿子节点放入队列尾
count++;
}
}while(count);//循环把同层树节点入队列尾,再在队列头输出每一层
}
int TreeLeaf(BiTree T)
{
static int i = 0;
if(NULL == T)
return 0;
if(T->lchild)
TreeLeaf(T->lchild);
if(T->rchild)
TreeLeaf(T->rchild);//递归调用判断是否为叶子节点
if(!T->lchild &&!T->rchild)
i++;//是叶子节点i自增
return i;
}