数据结构 二叉树的应用算法

/*这里我们只要讲一下,就是建立二叉树了。有二种建立二叉树的
方法。我们讲一下。*/


#include <stdio.h>
#include <malloc.h>
#define MAX 20
typedef struct BiTNode
{
char date;
struct BiTNode* lchild,*rchild;
}*BiTree;
void CreateBiTree_1(BiTree*);//第一种方法二级指针建立二叉树。
BiTree CreateBiTree_2();//第二种方法,返回根指针。
void PreOrderBiTree(BiTree);//先序遍历
void InOrderBiTree(BiTree);//中序遍历
void PostOrderBiTree(BiTree);//后序遍历


BiTree Destory(BiTree);//后序销毁指定的根节点。
BiTree GetParent(BiTree,char);//求指定字符的双亲节点
BiTree FindNode(BiTree,char);//查找二叉树指定的节点
BiTree MaxNode(BiTree);//求指点的最大值
void LevelOrder(BiTree);//层次遍历二叉树
int depth(BiTree);//求二叉树的深度
void leavescount(BiTree,int*);


int main(void)
{
char ch,c;
int count=0;//首先将叶子节点的个数初始化为0
BiTree T,BT,BN;//初始化为空指针。
//CreateBiTree_1(&T);//建立二叉树
BN= CreateBiTree_2();//第二种方法建立二叉树
printf("先序遍历:");
PreOrderBiTree(BN);
printf("\n中序遍历:");
InOrderBiTree(BN);
printf("\n后序遍历:");
PostOrderBiTree(BN);
printf("\n");
getchar();
printf("请输入你要查找的节点:");
scanf("%c",&ch);
BT=FindNode(BN,ch);
if(BT==NULL)
printf("没有查找到给节点!\n");
else
printf("该节点为%c\n",BT->date);
getchar();
printf("请输入你要查找节点的双亲节点:");
scanf("%c",&c);
T=GetParent(BN,c);
if(T==NULL)
printf("该节点没有双亲节点!\n");
else
printf("该节点的双亲节点为%c\n",T->date);
leavescount(BN,&count);//注意此时我们调用的根节点是创建二叉树的根节点。
printf("该叶子的个数为%d\n",count);
printf("树的深度为%d!\n",depth(BN));
printf("二叉树的层次遍历:\n");
LevelOrder(BN);
printf("\n");
BT=MaxNode(BN);
printf("二叉树中节点的最大值为%c\n",BT->date);
return 0;
}
void CreateBiTree_1(BiTree*T)
{
char ch;
ch=getchar();
if(ch=='#')
(*T)=NULL;//'#'代表空指针。
else
{
(*T)=(BiTree)malloc(sizeof(struct BiTNode));//申请节点
(*T)->date=ch;
CreateBiTree_1(&(*T)->lchild);
CreateBiTree_1(&(*T)->rchild);
}
return;
}
BiTree CreateBiTree_2()
{
BiTree T=NULL;
char ch;
ch=getchar();
if(ch=='#')
T=NULL;//'#'代表空指针。
else
{
T=(BiTree)malloc(sizeof(struct BiTNode));//申请节点
T->date=ch;
T->lchild=CreateBiTree_2();
T->rchild=CreateBiTree_2();
}
return T;
}
void PreOrderBiTree(BiTree T)
{
if(T)
{
printf("%c ",T->date);
PreOrderBiTree(T->lchild);
PreOrderBiTree(T->rchild);
}
return ;
}
void InOrderBiTree(BiTree T)
{
if(T)
{
PreOrderBiTree(T->lchild);
printf("%c ",T->date);
PreOrderBiTree(T->rchild);
}
return ;
}
void PostOrderBiTree(BiTree T)
{
if(T)
{
PreOrderBiTree(T->lchild);
PreOrderBiTree(T->rchild);
printf("%c ",T->date);
}
return ;
}
BiTree FindNode(BiTree BT,char ch)
{
BiTree BN=NULL;
if(!BT)//如果为根节点为空树 的话,为NULL.
return NULL;
else if(BT->date==ch)
return BT;
BN=FindNode(BT->lchild,ch);//对其左子树进行查找
if(BN==NULL)//如果左子树没有找到
BN=FindNode(BT->rchild,ch);
return BN;
}
BiTree GetParent(BiTree BT,char ch)
{
BiTree Parent=NULL;
if(!BT||BT->date==ch)//如果根节点没有双亲节点或者为空树 的话
return NULL;
if((BT->lchild&&BT->lchild->date==ch)||(BT->rchild&&BT->rchild->date==ch))//必须先要判断左右子数不为空的前提下,在判断是否相等。
return BT;
Parent=GetParent(BT->lchild,ch);
if(Parent==NULL)//左子树没有找到话,我们就查找右子树
Parent=GetParent(BT->rchild,ch);
return Parent;
}
void leavescount(BiTree BT,int*count)
{
if(BT)
{
if(BT->lchild==NULL&&BT->rchild==NULL)
++(*count);
leavescount(BT->lchild,count);
leavescount(BT->rchild,count);
}
}
BiTree Destory(BiTree BT)//采用后序遍历法
{//释放指定子树所有的节点,指向根节点的指针制空
if(!BT)
{
Destory(BT->lchild);
Destory(BT->rchild);
free(BT);
}


return NULL;
}
int depth(BiTree BT)
{
int depth1,depth2;
if(!BT)//我们规定二叉树为空的话,深度为0,否侧求的就是左右子树深度的最大值。
return 0;
else
{
depth1=depth(BT->lchild);
depth2=depth(BT->rchild);
return (depth1>depth2?(depth1+1):(depth2+1));
}
}
void LevelOrder(BiTree BT)//用队列遍历二叉树
{
BiTree Queue[MAX],T;//定义了结构体指针数组。每一个数据用来存放对应的指针。
int rear,front;
front=rear=0;
if(BT)
{
Queue[rear++]=BT;//数不为空的话,将根节点入队。
while(front!=rear)
{
T=Queue[front++];//队列不为空的话,就将队首元素出队。
printf("%2c",T->date);
if(T->lchild)Queue[rear++]=T->lchild;//不空的前提下,我们入队
if(T->rchild)Queue[rear++]=T->rchild;
}
}
return ;
}
BiTree MaxNode(BiTree BT)
{
BiTree Pmax,temp;
if(BT==NULL)
return NULL;
Pmax=BT;//以当前跟节点为最大值
temp=MaxNode(BT->lchild);//求左子树的最大根节点。
if(temp)//左子树存在的话
{
if(temp->date>Pmax->date)
Pmax=temp;
}
temp=MaxNode(BT->rchild);
if(temp&&temp->date>Pmax->date)
Pmax=temp;
return Pmax;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值