二叉树的应用
#include<stdio.h>
#include"malloc.h"
#define N 1000
typedef char DataType;
typedef struct bnode{
DataType data;
struct bnode * lchild, *rchild;
} Bnode,*BTree;
/*******二叉树的创建*********/
//算法6.11 创建二叉链表存储的二叉树
/*按照二叉树的遍历的思想即可*/
BTree CreateBinTree()
{
/* 以加入空结点的先序序列输入,构造二叉链表 */
char ch;
BTree t;
ch = getchar(); //不断的从控制台获取数据 作为结点的数据域
if (ch == '#') t = NULL; /*读入#时,将相应结点指针置空*/
else
{
t = (BTree)malloc(sizeof(Bnode)); /* 生成结点空间 */
t->data = ch;
t->lchild = CreateBinTree(); /*构造二叉树的左子树 */
t->rchild = CreateBinTree(); /*构造二叉树的右子树 */
}
return t;
}
//访问结点
void Visit(DataType data)
{
printf("%-3c", data);
}
//先序递归遍历
void PreOrder (BTree t){
if(t){
Visit(t->data);
PreOrder (t->lchild);
PreOrder (t->rchild);
}
}
/*******************************叶子结点************************************/
//1.统计二叉树的叶子结点的数量
/* 叶子结点:没有左子树也没有右子树的结点
1.先设置一个计数器,记录叶子结点的数量m
2.遍历过程中,判断是否为叶子结点
是: m+1;
3.直到遍历结束,就可以得到叶子结点的数量了
<这里用先序遍历方法递归实现>
*/
void numfleaf(BTree t , int &m)
{/*这里的m是引用型形参,每一次递归调用前都可以实时记录叶子结点的个数*/
if(t){
if(t->lchild==NULL && t->rchild==NULL){/*左右子树为空*/
m++; /*叶子结点计数器加1*/
}
numfleaf(t->lchild,m);
numfleaf(t->rchild,m);//递归遍历左右子树
}
}
/*******************************叶子结点************************************/
//算法实现左右孩子交换
void Exchange(BTree t)//算法实现左右孩子交换
{
BTree p;
if(t)
{
p=t->lchild;
t->lchild=t->rchild;
t->rchild=p;
Exchange(t->lchild);
Exchange(t->rchild);
}
}
// 递归在二叉树中求位于先序序列中第k位置的结点值
int c; //计数器c作为全局变量处理,初始值为0
void Get_PreSeq(BTree T, int k) //线序序列为k的结点的值
{
if(T)
{
c++; //每访问一个子树的根都会使线序序号计数器加1
if(c==k)
{
printf("\n指定结点的值是%d\n",T->data);
//exit(1);
}
else
{
Get_PreSeq(T->lchild,k); //在左子树中查找
Get_PreSeq(T->rchild,k); //在右子树中查找
}
}
}
//主调函数示例:
int main()
{
//输入示例:ABC#DEF####G### ;
BTree t;
int m;
int k;
t=CreateBinTree();//先建立二叉树;
m=0; //全局变量m置初始值
numfleaf(t ,m);//求t树叶子结点的个数
printf("\n叶子结点的个数:m = %d\n",m); //输出结果
k = 2; //先默认一个值,可以换换试试
Get_PreSeq(t,k); //线序序列为k的结点的值
/*函数里有输出语句,所以这里不printf()了*/
Exchange(t);//算法实现左右孩子交换
printf("\n交换左右孩子后层次遍历二叉树:\n");
PreOrder(t);
printf("\n");
return 0;
}