二叉树的应用
(1) 创建一棵二叉树;
(2) 二叉树的先序递归遍历;
(3) 二叉树的中序递归遍历;
(4) 二叉树的后序递归遍历;
(5) 二叉树的层次遍历;
(6) 计算二叉树的深度;
(7) 统计二叉树中的叶子结点的个数;
(8) 统计二叉树中度为2的节点数;
(9) 输入任一结点值,输出其左、右孩子结点值;
(10) 输出某一结点在二叉树中的层数;
#include<stdio.h>
#include<stdlib.h>
#define MAX 100
int count = 0; //定义计算结点个数的变量
typedef struct tnode{
char data; //二叉树结点值
struct tnode *lchild,*rchild;
}BT;
/*以先序序列输入结点的值*/
BT *CreateBTree(){
BT *t;
char ch;
scanf("%c",&ch);
getchar();
if(ch=='0')
t = NULL;
else{
t = (BT*) malloc (sizeof (BT));
t->data = ch;
printf("请输入%c结点的左孩子的结点:",t->data);
t->lchild = CreateBTree();
printf("请输入%c结点的右孩子的结点:",t->data);
t->rchild = CreateBTree();
}
return t;
}
/*先序遍历二叉树*/
void PreOrder(BT *T){
if(T == NULL)
return;
else{
printf("%c",T->data); //输出结点的数据域
PreOrder(T->lchild); //先序遍历输出左子树
PreOrder(T->rchild); //先序遍历输出右子树
}
}
/*中序遍历二叉树*/
void InOrder(BT *T){
if(T == NULL)
return;
else{
InOrder(T->lchild);
printf("%c",T->data);
InOrder(T->rchild);
}
}
/*后序遍历二叉树*/
void PostOrder(BT *T){
if(T == NULL)
return;
else{
PostOrder(T->lchild);
PostOrder(T->rchild);
printf("%c",T->data);
}
}
/*二叉树的层次遍历*/
void LevelOrder(BT *T){
int f,r; //f:队列的头下标 r:队尾下一个位置的下标
BT *p,*q[MAX];
p = T;
if(p != NULL){ //若二叉树非空,则根结点地址入队
f = 1;
q[f] = p;
r = 2;
}
while(f != r){ //队列不为空时
p = q[f]; //用指针p 获取队首结点
printf("%c",p->data);
if(p->lchild != NULL){
q[r] = p->lchild;
r = (r+1) % MAX;
}
if(p->rchild != NULL){
q[r] = p->rchild;
r = (r+1) % MAX;
}
f = (f+1) % MAX;
}
}
/*计算二叉树的深度*/
int TreeDepth(BT *T){
int ldep,rdep;
if(T == NULL)
return 0;
else{
ldep = TreeDepth(T->lchild);
rdep = TreeDepth(T->rchild);
if(ldep > rdep)
return ldep+1;
else
return rdep+1;
}
}
/*叶子结点的个数*/
void LeafNum(BT *T){
if(T){ //若树不为空
if(T->lchild==NULL && T->rchild==NULL)
count++;
LeafNum(T->lchild);
LeafNum(T->rchild);
}
}
/*二叉树中度为2的节点数*/
int TwoNodesNum(BT *T){
if (T == NULL)
return 0;
if (T->lchild != NULL && T->rchild != NULL)
return 1 + TwoNodesNum(T->lchild) + TwoNodesNum(T->rchild);
return TwoNodesNum(T->lchild) + TwoNodesNum(T->rchild);
}
/*输入任一结点值,输出其左、右孩子结点值*/
void GetChild(BT *T, char date_pre){
if(T == NULL)
return;
else{
if(T->data == date_pre)
{
if(T->lchild==NULL && T->rchild==NULL){
printf("该结点为叶子结点,无左右孩子\n");
return;
}
else if(T->lchild!=NULL && T->rchild==NULL){
printf("%c的左孩子结点:%c\n%c无右孩子结点\n",T->data,T->lchild->data,T->data);
return;
}
else if(T->lchild==NULL && T->rchild!=NULL){
printf("%c无左孩子结点\n%c的右孩子结点:%c\n",T->data,T->data,T->rchild->data);
return;
}
else{
printf("%c的左孩子结点:%c\n%c的右孩子结点:%c\n",T->data,T->lchild->data,T->data,T->rchild->data);
return;
}
}
GetChild(T->lchild,date_pre); //先序遍历输出左子树
GetChild(T->rchild,date_pre); //先序遍历输出右子树
}
}
/*查找date_pre在第几层*/
int Get_Level(BT *Q, char date_pre, int height){
int h;
if(Q == NULL)
return 0;
else{
if(Q->data == date_pre)
return height;
else{
h = Get_Level(Q->lchild,date_pre,height+1);
if (h!=0)
return(h);
else
return(Get_Level(Q->rchild,date_pre,height+1));
}
}
}
void MenuTree()
{
printf(" 二叉树的各种操作");
printf("\n==================================================");
printf("\n| 1--创建一棵二叉树 |");
printf("\n| 2--二叉树的先序递归遍历 |");
printf("\n| 3--二叉树的中序递归遍历 |");
printf("\n| 4--二叉树的后序递归遍历 |");
printf("\n| 5--二叉树的层次遍历 |");
printf("\n| 6--计算二叉树的深度 |");
printf("\n| 7--统计二叉树中的叶子结点的个数 |");
printf("\n| 8--统计二叉树中度为2的节点数 |");
printf("\n| 9--输入任一结点值,输出其左、右孩子结点值 |");
printf("\n| M--输出某一结点在二叉树中的层数 |");
printf("\n| 0--返回 |");
printf("\n==================================================");
printf("\n请输入菜单号(0-10):");
}
main(){
BT *T=NULL;
int f;
char choice,a,m;
while(1){
MenuTree();
scanf("%c",&choice);
getchar();
switch(choice){
case '1':
printf("请按先序遍历输入二叉树的结点:\n");
printf("输入结点后按回车('0'表示该结点为空)\n");
printf("请输入根结点:");
T = CreateBTree();
printf("二叉树建立成功!\n");
break;
case '2':
printf("二叉树的先序遍历为:");
PreOrder(T);
break;
case '3':
printf("二叉树的中序遍历为:");
InOrder(T);
break;
case '4':
printf("二叉树的后序遍历为:");
PostOrder(T);
break;
case '5':
printf("二叉树的层次遍历为:");
LevelOrder(T);
break;
case '6':
printf("二叉树的深度是:%d",TreeDepth(T));
break;
case '7':
count = 0;
LeafNum(T);
printf("二叉树中的叶子结点的个数是:%d",count);
break;
case '8':
printf("该二叉树中度为2的节点数:%d",TwoNodesNum(T));
break;
case '9':
char num_pre;
printf("输入任一结点值,输出其左、右孩子结点值");
scanf("%c",&num_pre);
GetChild(T,num_pre);
break;
case 'M':
int level;
char search_level;
printf("请输入要查找的结点:");
scanf(" %c",&search_level);
level = Get_Level(T,search_level,1);
if(level!=101)
printf("%c结点的高度为%d",search_level,level);
else
printf("二叉树中没有该结点");
break;
case '0':
exit(1);
default:
printf("输入有误,请重新在0-10中选择!");
}
if(choice != '0'){
printf("\n按回车继续,按任意键返回主菜单!\n");
a = getchar();
if(a != '\xA'){
getchar();
exit(1);
}
}
}
}

