二叉树的基本操作

时间:2022-03-22 17:27:32

加入博客园20多天,终于开始着手写自己的第一篇博客了。树型结构是一类重要的非线性数据结构,其中以树和二叉树最为常用。其中二叉树的基本操作包括二叉树的存储结构、二叉树的遍历(先序、中序、后序)、打印遍历结果、统计二叉树中结点和叶子节点的个数,二叉树的高度以及以树状形式打印出相应编号。

源程序编译如下:

#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<conio.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef char TElemType;
typedef struct BiTNode
{
TElemType data;
struct BiTNode *LChild,*RChild;
}BiTNode,*BiTree;


int LeafCount; //保存叶子结点的总数

int CreateBiTree(BiTree *T)
{// 此处输入用扩展先序遍历建立二叉树的代码
char ch;
scanf("%c",&ch);
if(ch=='#')*T=NULL;
else
{
*T=(BiTree)malloc(sizeof(BiTNode)); //开辟空间
(*T)->data=ch;//赋值
CreateBiTree(&((*T)->LChild));
CreateBiTree(&((*T)->RChild));
}
return OK;
}
int Visit(TElemType e)//查找函数
{
printf("%c",e);
return OK;
}
void PreOrder(BiTree T)
/*先序遍历二叉树,T为指向二叉树根结点的指针*/
{
if (T!=NULL)
{
Visit(T->data); /*访问根结点*/
PreOrder(T->LChild); /*先序遍历左子树*/
PreOrder(T->RChild); /*先序遍历右子树*/
}
}
void InOrder(BiTree T)
/*中序遍历二叉树,T为指向二叉树根结点的指针*/
{ if (T!=NULL)
{
InOrder(T->LChild); /*中序遍历左子树*/
Visit(T->data); /*访问根结点*/
InOrder(T->RChild); /*中序遍历右子树*/
}


}
void PostOrder(BiTree T)
/*后序遍历二叉树,T为指向二叉树根结点的指针*/
{ if(T!=NULL)
{
PostOrder(T->LChild); /*后序遍历左子树*/
PostOrder(T->RChild); /*后序遍历右子树*/
Visit(T->data); /*访问根结点*/
}

 

}
int NodeCount;
//此处输入统计结点的代码
int CountNode(BiTree T)
{
/*if(!T)
return 0;
else
return 1+CountNode(T->LChild)+CountNode(T->RChild);*/
if(T!=NULL)
{
printf("%c",T->data);
NodeCount++;
CountNode(T->LChild);
CountNode(T->RChild);
}
return OK;
}
//此处输入统计叶子结点的代码
void Leaf(BiTree T)
{ if(T!=NULL)
{
Leaf(T->LChild);
Leaf(T->RChild);
if (T->LChild==NULL && T ->RChild==NULL)
LeafCount++;
}


}
int PostTreeDepth(BiTree bt) /*后序遍历求二叉树的高度递归算法*/
{int hl, hr, max;
if(bt!=NULL)
{
hl=PostTreeDepth(bt->LChild); /* 求左子树的深度 */
hr=PostTreeDepth(bt->RChild); /* 求右子树的深度 */
max=hl>hr?hl: hr; /* 得到左、 右子树深度较大者*/
return(max+1); /* 返回树的深度 */
}
else return(0); /* 如果是空树, 则返回0 */
}
void PrintTree(BiTree bt,int nLayer)
{//按竖向树状输出二叉树。输出结果顺时针方向旋转90度即为原二叉树。
if(bt==NULL)return;
PrintTree(bt->RChild,nLayer+1);
for(int i=0;i<nLayer;i++)
printf(" ");
printf("%c\n",bt->data);
PrintTree(bt->LChild,nLayer+1);
}

void main()
{
BiTree T;
int nLayer=1;
printf("按扩展先序遍历序列建立二叉树,请输入序列:\n");
if(!(CreateBiTree(&T)))
printf("创建二叉树失败\n");
else
printf("创建二叉树成功\n");
printf("先序遍历输出序列为:\n");
PreOrder(T);
printf("\n");
getch();
printf("中序遍历输出序列为:\n");
InOrder(T);
printf("\n");
getch();
printf("后序遍历输出序列为:\n");
PostOrder(T);
printf("\n");
getch();
CountNode(T);
printf("二叉树的结点总数为:%d\n",NodeCount);
printf("\n");
Leaf(T);
printf("二叉树的叶子结点总数为:%d\n",LeafCount);
printf("二叉树的高度为:%d\n",PostTreeDepth(T));
printf("树状输出二叉树为:\n");
PrintTree(T,nLayer);
}

写程序时出现的问题以及解决方式:

1、在创建函数时设置的退出方式最初为遇见空格即退出,但由于输入时会把空格屏蔽掉,故陷入死循环中退不出来,改为遇'#'时即可退出;

2、在统计结点总数时本应采用递归调用,却粗心写成了先序遍历。