#include<stdio.h>
#include<stdlib.h>
typedef char TElemType; //数据域类型为字符型
typedef struct BiTNode{ //定义二叉链表的结构体及类型
TElemType data; //结点数据域
struct BiTNode *lchild, *rchild; //左右孩子指针
}BiTNode, *BiTree;
//先序遍历创建二叉树
void CreateBiTree(BiTree *T) //二级指针
{
char ch;
scanf("%c",&ch); //读入字符
if(ch=='#') //如果读入字符为#
{
*T=NULL; //指针指向空
}
else
{
*T=(BiTNode*)malloc(sizeof(BiTNode)); //生成根结点
(*T)->data=ch; //根结点数据域置为ch
CreateBiTree( &((*T)->lchild ) );//递归建立左子树 ,(*T)->lchild 为一级指针,要取地址变二级指针
CreateBiTree( &((*T)->rchild ) );//递归建立右子树
}
return;
}
/*BiTNode*CreateBiTree()
{
char ch;
BiTNode *T;
scanf("%c",&ch);
if(ch == '#') T = NULL;
else{
T = (BiTNode*)malloc(sizeof(BiTNode)); //生成根结点
T->data = ch; //根结点数据域置为ch
T->lchild = NULL;
T->rchild = NULL;
T->lchild=CreateBiTree(); //递归创建左子树
T->rchild=CreateBiTree(); //递归创建右子树
}
return T;
} */
//遍历二叉树
void PreOrderTraverse(BiTree T)//先序遍历
{
if(T==NULL)
return;
else
{
printf(" %c " , T->data); //根
PreOrderTraverse(T->lchild); //左
PreOrderTraverse(T->rchild); //右
}
}
void InOrderTraverse(BiTree T)//中序遍历
{
if(T==NULL)
return;
else
{
InOrderTraverse(T->lchild); //左
printf(" %c ", T->data); //根
InOrderTraverse(T->rchild); //右
}
}
void PostOrderTraverse(BiTree T)//后序遍历
{
if(T==NULL)
return;
else
{
PostOrderTraverse(T->lchild); //左
PostOrderTraverse(T->rchild); //右
printf(" %c " , T->data); //根
}
}
//计算二叉树的深度
int Depth(BiTree T)
{
int m,n;
if(T == NULL) return 0; //如果是空树,深度为0,递归结束
else
{
m = Depth(T->lchild); //递归计算左子树的深度记为m
n = Depth(T->rchild); //递归计算右子树的深度记为n
if(m > n) //二叉树的深度为m与n的较大者加1
return (m+1);
else
return (n+1);
}
}
//统计二叉树中结点的个数
int NodeCount(BiTree T)
{
if(T == NULL) return 0; //如果是空树,则结点个数为0,递归结束
else //否则结点个数为左子树中结点个数+右子树中结点个数+1
return NodeCount(T->lchild)+NodeCount(T->rchild)+1;
}
//统计二叉树的叶子的结点个数
int LeavesCount(BiTree T)
{
if(T == NULL) return 0; //如果是空树,则结点个数为0,递归结束
else
if(T->lchild == NULL &&T->rchild == NULL) //没有左右子树,是叶子,返回1
return 1;
else
{ //否则叶子的结点个数为左右子树中叶子的结点个数之和
return LeavesCount(T->lchild)+ LeavesCount(T->rchild);
}
}
//统计二叉树的度为1的结点个数
int OneCount(BiTree T)
{
if(T == NULL) return 0; //如果是空树,则结点个数为0,递归结束
else
if((T->lchild == NULL &&T->rchild != NULL)||(T->lchild != NULL &&T->rchild == NULL))
{ //如果左子树为空且右子树不空,或者左子树不空且右子树为空,
//度为1结点个数为左子树中度为1结点个数+右子树中度为1结点个数+1
return OneCount(T->lchild)+OneCount(T->rchild)+1;
}
else
{ //否则度为1结点个数为左子树中度为1结点个数+右子树中度为1结点个数
return OneCount(T->lchild)+OneCount(T->rchild);
}
}
//输出二叉树中从每个叶子结点到根结点的路径
void Allpath(BiTNode *T,TElemType path[],int pathlen)
{ //先序遍历方法输出每个叶子结点到根结点的路径序列
int i;
if(T!=NULL)
{ if (T->lchild == NULL && T->rchild==NULL) //T为叶子
{
printf("%c->",T->data); //输出叶子
for (i=pathlen-1; i>0; i--) //循环输出叶子到根之间的结点
printf("%c->", path[i]);
printf("%c\n", path[0]); //根
}
else //递归
{
path[pathlen++] = T->data;
Allpath(T->lchild, path, pathlen); //递归左子树每个叶子结点到根结点的路径序列
Allpath(T->rchild, path, pathlen); //递归右子树每个叶子结点到根结点的路径序列
}
}
}
//主函数
int main()
{
BiTree Tree;
char path[100]; //定义一个数组存放结点序列
printf("先序遍历的顺序输入:\n");
CreateBiTree(&Tree); //创建二叉树
printf("\n先序遍历:\n");
PreOrderTraverse(Tree);
printf("\n中序遍历:\n");
InOrderTraverse(Tree);
printf("\n后序遍历:\n");
PostOrderTraverse(Tree);
printf("\n");
printf("\n二叉树的深度为:%d\n",Depth(Tree));
printf("\n二叉树中的结点个数为:%d\n",NodeCount(Tree));
printf("\n二叉树的叶子的结点个数:%d\n",LeavesCount(Tree));
printf("\n二叉树中度为1的结点个数:%d\n",OneCount(Tree));
printf("\n输出二叉树中从每个叶子结点到根结点的路径:\n");
Allpath(Tree,path,0);
return 0;
}
数据结构——二叉树
最新推荐文章于 2023-05-26 21:38:20 发布