二叉树的基本操作很烦,一个搞不好脑袋就炸了,二叉树最重要的操作就是遍历,而二叉树的操作都是基于遍历实现的,(比如:求叶子节点的个数、求二叉树的深度、求节点的总个数)而遍历最常用的方法就是递归
工欲善其事必先利其器
首先把变量定义好
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 10000
#define STACK_SIZE 100
#define OK 1
#define ERROR -1
typedef char ElemType;//二叉树中值的类型,可以根据需要更改
typedef int Status;
定义二叉树的结构体
typedef struct BTNode
{
ElemType data;
struct BTNode *Lchild, *Rchild;
}BTNode;
栈的结构体
typedef struct SqStack
{
int top;
int bottom;
BTNode array[STACK_SIZE];
int stacksize;/*当前已分配空间,以元素为单位*/
}SqStack;
初始化栈
Status Init_Stack(SqStack *S)
{
if(!S->bottom)
{
printf("initialize fail\n");
exit(-1);
}
S->top = S->bottom = 0;
S->stacksize = STACK_SIZE;
return OK;
}
入栈
Status Push(SqStack *S, BTNode *B)
{
if (S->top - S->bottom == STACK_SIZE - 1)//栈满
{
return ERROR;
}
S->array[S->top] = *B;
S->top++;
return OK;
}
弹出栈顶元素
BTNode Pop(SqStack *S)
{
BTNode B;
if (S->bottom == S->top)
{
printf("This stack is empty!\n\n");
exit(0);
}
else
{
B = S->array[(S->top) - 1];
S->top--;
}
return B;
}
二叉树的初始化(初始化一棵空二叉树)
Status Init_BTNode(BTNode *T)
{
T->Lchild = NULL;
T->Rchild = NULL;
T->data = '\0';
return OK;
}
创建一颗二叉树
Status Create_BTNode(BTNode *T)
{
char ch;//树根的值
BTNode *L;//左子树
BTNode *R;//右子树
char lc;//是否有左子树判断符
char rc;//是否有右子树判断符
L = (BTNode *)malloc(sizeof(BTNode));
R = (BTNode *)malloc(sizeof(BTNode));
T->Lchild = L;
T->Rchild = R;
printf("data:\n");
fflush(stdin);//从控制台读取字符类型 保证不出现异常
scanf("%c", &ch);
if(ch == ' ')//空树
{
T->Lchild = NULL;
T->Rchild = NULL;
}
else
{
T->data = ch;
printf("Does %c has left child?(Y|N)\n", T->data);
fflush(stdin);
scanf("%c", &lc);
while(lc != 'Y' && lc != 'y' && lc != 'N' && lc != 'n')
{
printf("error!\t please enter again\n");
fflush(stdin);
scanf("%c", &lc);
}
if(lc == 'y' || lc == 'Y')
{
Create_BTNode(L);
}
else
{
T->Lchild = NULL;
free(L);
}
printf("Does %c has right child?(Y|N)\n", T->data);
fflush(stdin);
scanf("%c", &rc);
while(rc != 'Y' && rc != 'y' && rc != 'N' && rc != 'n')
{
printf("error!\t please enter again\n");
fflush(stdin);
scanf("%c", &rc);
}
if(rc == 'Y' || rc == 'y')
{
Create_BTNode(R);
}
else
{
T->Rchild = NULL;
free(R);
}
}
return OK;
}
遍历二叉树
//先序遍历(递归)
Status PreOrderTraverse(BTNode *T)
{
if(T != NULL)
{
printf("%c", T->data);
PreOrderTraverse(T->Lchild);
PreOrderTraverse(T->Rchild);
}
return OK;
}
//中序遍历(递归)
Status InOrderTraverse(BTNode *T)
{
if(T != NULL)
{
InOrderTraverse(T->Lchild);
printf("%c", T->data);
InOrderTraverse(T->Rchild);
}
return OK;
}
//后序遍历(递归)
Status PosOrderTraverse(BTNode *T)
{
if(T != NULL)
{
PosOrderTraverse(T->Lchild);
PosOrderTraverse(T->Rchild);
printf("%c", T->data);
}
return OK;
}
求二叉树的节点总个数
Status child(BTNode *T)
{
int Lchildnumber = 0;
int Rchildnumber = 0;
if(T->Lchild != NULL)
Lchildnumber = child(T->Lchild);
if(T->Rchild != NULL)
Rchildnumber = child(T->Rchild);
return Lchildnumber + Rchildnumber + 1;//返回每个节点的左右节点加上本身
}
求叶子结点个数
int leafchild(BTNode *T)
{
int Lleafchild = 0;
int Rleafchild = 0;
if(T->Lchild != NULL)
Lleafchild = leafchild(T->Lchild);
if(T->Rchild != NULL)
Rleafchild = leafchild(T->Rchild);
if(T->Lchild == NULL && T->Rchild == NULL)
return 1;
else
return Lleafchild + Rleafchild;
}
求二叉树的深度
int depth(BTNode *T)
{
int Rdepth = 0;
int Ldepth = 0;
if(T->Lchild != NULL)
Ldepth = depth(T->Lchild);
if(T->Rchild != NULL)
Rdepth = depth(T->Rchild);
return(Rdepth > Ldepth) ? Rdepth + 1 : Ldepth + 1;//返回每个节点的左、右长度较大的一个加一
}
主方法
int main()
{
int a;
int flag = 0;//初始化的标志位
int tag = 0;//建立二叉树的标志位
BTNode T;
printf("1.initializeBTNode\n2.createBTNode\n3.travelBTNode\n4.child number\n5.BiTreeDepth\n6.leaf child\n");
printf("hello\n");
while(1)
{
printf("please enter operation code:");
scanf("%d", &a);
switch(a)
{
case 1:
a = Init_BTNode(&T);
flag++;
if(a == 1)
{
printf(" success\n");
}
else
{
printf(" fail\n");
}
break;
case 2:
if(flag == 0)
{
printf(" please initialize binary tree fist!\n");
}
else
{
Create_BTNode(&T);
tag++;
}
break;
case 3:
if(flag == 0)
{
printf(" please initialize binary tree fist!\n");
}
else
{
if(tag == 0)
{
printf("please build a binary tree first!");
}
else
{
int o;
printf("1.Previous Order Traverse1\n2.Previous Order Traverse\n3.Infix Order Traverse\n4.Posterior Order Traverse\n");
scanf("%d", &o);
switch(o)
{
case 1:
PreOrderTraverses1(&T);
printf("\n");
break;
case 2:
PreOrderTraverse(&T);
printf("\n");
break;
case 3:
InOrderTraverse(&T);
printf("\n");
break;
case 4:
PosOrderTraverse(&T);
printf("\n");
break;
default :
printf("operating code error\n");
break;
}
}
}
break;
case 4:
if(flag == 0)
{
printf(" please initialize binary tree fist!\n");
}
else
{
if(tag == 0)
{
printf("please build a binary tree first!");
}
else
{
printf("the number of child is : %d\n",child(&T));
}
}
break;
case 5:
if(flag == 0)
{
printf(" please initialize binary tree fist!\n");
}
else
{
if(tag == 0)
{
printf("please build a binary tree first!");
}
else
{
printf("the depth is : %d\n", depth(&T));
}
}
break;
case 6:
if(flag == 0)
{
printf(" please initialize binary tree fist!\n");
}
else
{
if(tag == 0)
{
printf("please build a binary tree first!");
}
else
{
printf("the leaves child is : %d\n", leafchild(&T));
}
}
break;
default:
printf(" operating code error.\n please enter again.\n");
}
}
return 0;
}