为了防止有的小伙伴混淆,在看代码之前我先说明一下,CreateBinTree函数只是我个人比较喜欢的创建一个简单二叉树的方法,当然此外还有很多其他方法创建二叉树,在此不表。因为是递归调用,所以在开始使用这个函数创建的时候,最好直接输入一个字符串,当然你愿意一个一个输入字符也可以;不过这个字符串必须是先序序列,没有孩子的地方以’#’代替,一个空二叉树就是’#’,只有根节点的二叉树就是’a##’,’a’为根节点的值。
#include<stdio.h>
#include<stdlib.h>
//暂定数据类型为字符型char
typedef char ElemType;
//存储结构
typedef struct BinNode{
ElemType Data;
struct BinNode *Left, *Right;
}*BinTree;
//创建二叉树
BinTree CreateBinTree();
//先序递归遍历
void PreOrderTraversal( BinTree T );
//中序递归遍历
void InOrderTraversal( BinTree T );
//后序递归遍历
void PostOrderTraversal( BinTree T );
//计算树的深度(高度)
int Depth(BinTree T);
//打印某层节点
void PrintNodeAtLevel(BinTree T, int level);
//层次递归遍历
void LevelOrderTraversal(BinTree T);
//计算叶子节点数目
int LeafNodeCount(BinTree T);
//计算值为Data的节点的深度
int NodeDepth(BinTree T,ElemType Data);
//主函数
//------------------------------------------------------------------------------------------------------------------------------------------
int main()
{
BinTree T = CreateBinTree();
printf("PreOrder: ");
PreOrderTraversal(T);
printf("\n");
printf("InOrder: ");
InOrderTraversal(T);
printf("\n");
printf("PostOrder: ");
PostOrderTraversal(T);
printf("\n");
LevelOrderTraversal(T);
printf("叶子节点数为%d\n",LeafNodeCount(T));
//深度为0代表没找到
printf("值为'4'的节点深度为%d\n",NodeDepth(T,'4'));
}
//------------------------------------------------------------------------------------------------------------------------------------------
//创建二叉树
/*构造时候,在先序排列里每个叶子节点后加入两个'#',只有一个孩子的分支节点在空位上补#,将此字符串输入,此处是按照先序设计的CreateBinTree函数,
即输入'124##5##36##7##'就是一个3层的满二叉树,如果想改造成中序或者后序设计,仿照递归遍历设计即可*/
BinTree CreateBinTree()
{
ElemType ch;
scanf("%c",&ch);
BinTree T;
if(ch=='#') T = NULL;
else
{
T = (BinTree)malloc(sizeof(struct BinNode));
if(!T)
{
printf("Error!");
return NULL;
}
T->Data = ch;//这句也可以放在Left或者Right后面
T->Left = CreateBinTree();
T->Right = CreateBinTree();
}
return T;
}
//先序递归遍历
void PreOrderTraversal( BinTree T )
{
if( T ) {
printf("%c ", T->Data );
PreOrderTraversal( T->Left );
PreOrderTraversal( T->Right );
}
}
//中序递归遍历
void InOrderTraversal( BinTree T )
{
if( T ) {
InOrderTraversal( T->Left );
printf("%c ", T->Data);
InOrderTraversal( T->Right );
}
}
//后序递归遍历
void PostOrderTraversal( BinTree T )
{
if( T ) {
PostOrderTraversal( T->Left );
PostOrderTraversal( T->Right );
printf("%c ", T->Data);
}
}
//递归法求二叉树高度
int Depth(BinTree T)
{
int HL, HR, MaxH;
if(T)
{
HL = Depth(T->Left);
HR = Depth(T->Right);
MaxH = (HL > HR) ? HL : HR;
return MaxH + 1;
}
else return 0;
}
//打印某层的节点
void PrintNodeAtLevel(BinTree T, int level)
{ //空树或者层次不合理
if(T==NULL || level < 1) return;
if(level == 1)
{
printf("%c ",T->Data);
return;
}
//左子树的level-1级
PrintNodeAtLevel(T->Left,level - 1);
//右子树的level-1级
PrintNodeAtLevel(T->Right,level - 1);
}
//层次递归遍历
void LevelOrderTraversal(BinTree T)
{
if(T==NULL) return;
int depth = Depth(T);
int i;
for(i = 1;i <= depth;i++)
{
printf("第%d层:",i);
PrintNodeAtLevel(T,i);
printf("\n");
}
}
//计算叶子节点数目
int LeafNodeCount(BinTree T)
{
if(T==NULL) return 0;
else if(T->Left==NULL && T->Right==NULL) return 1;
else return LeafNodeCount(T->Left) + LeafNodeCount(T->Right);
}
//计算值为Data某节点的深度
int NodeDepth(BinTree T,ElemType Data)
{
if(T==NULL) return 0;
else if(T->Data==Data) return 1;
else if(T->Left==NULL && T->Right==NULL) return 0;
else
{
int L = NodeDepth(T->Left,Data);
int R = NodeDepth(T->Right,Data);
if(L) return L+1;
else if(R) return R+1;
else return 0;
}
}
先输入一个三层满二叉树
124##5##36##7##
输出
PreOrder: 1 2 4 5 3 6 7
InOrder: 4 2 5 1 6 3 7
PostOrder: 4 5 2 6 7 3 1
第1层:1
第2层:2 3
第3层:4 5 6 7
叶子节点数为4
值为’4’的节点深度为3
再输入一个三层非满的完全二叉树
abd##e##c##
输出
PreOrder: a b d e c
InOrder: d b e a c
PostOrder: d e b c a
第1层:a
第2层:b c
第3层:d e
叶子节点数为3
值为’4’的节点深度为0
最后输入一个最普通的四层二叉树
abd##e#g##cf###
输出
PreOrder: a b d e g d f
InOrder: d b e g a f d
PostOrder: d g e b f d a
第1层:a
第2层:b d
第3层:d e f
第4层:g
叶子节点数为3
值为’4’的节点深度为0
自己反复测试了一下这个代码,完全运行正常。如果有小伙伴发现程序有漏洞或者逻辑错误,欢迎在评论里指正