一、实验目的
1.掌握二叉链存储结构和掌握二叉树中各种基本运算算法设计。
2.掌握使用二叉树遍历算法进行二叉树问题求解。
二、实验内容
1.创建二叉树对应的二叉链存储结构。
2.输出二叉树。
3.输出二叉树b的高度。
4.输出二叉树b的结点个数。
5.输出二叉树b的叶子结点个数。
6.求二叉树b中指定结点值(假设所有结点值不同)的结点的层次。
三、实验代码及解释
创建文件BTree.cpp
#include <stdio.h>
#include <malloc.h>
#define MaxSize 100
typedef char ElemType;
typedef struct node
{
ElemType data;//数据元素
struct node * lchild;//指向左孩子结点
struct node * rchild;//指向右孩子结点
}BTNode;//声明二叉链结点类型
void CreateBTree(BTNode *&b,char *str)//创建二叉树,二叉树实现最主体部分
{
BTNode *St[MaxSize], *p;
int top=-1,k,j=0; //top定义首元节点,k作为一个区分左右子树的标记
char ch;
b=NULL; //建立的二叉树初始时为空
ch=str[j]; //声明一个字符数组,数组可以为任意内容
while(ch!='\0'){ //'\0'是字符串的结束符
switch(ch){
case '(': top++;St[top]=p;k=1;break; //'('左子树加一 ,k标记为1
case ')': top--;break; //')'返回父节点
case ',': k=2;break; //','右子树加一 ,k标记为2
default: //没有匹配的条件时,及异常处理
p=(BTNode *)malloc(sizeof(BTNode)); //malloc分配内存地址(sizeof用于获取指定类型或表达式的内存占用大小,以字节为单位))
p->data=ch;p->lchild=p->rchild=NULL; //左右子树都赋值为空
if(b==NULL)b=p; //这行代码的用途通常是在初始化或更新指针变量时。例如,在二叉树的插入操作中,可能需要创建一个新节点并将其链接到树中的某个位置。如果那个位置当前是空的(即对应的指针为 NULL),需要将新节点的地址赋给那个指针。
else{
switch(k){
case 1:St[top]->lchild=p;break;
case 2:St[top]->rchild=p;break;
}
}
}
j++;ch=str[j]; //一遍循环结束,将j的值传入ch为下一遍循环做准备
}
}
void DestroyBTree(BTNode * &b){ //释放所树节点
if(b!=NULL){
DestroyBTree(b->lchild);
DestroyBTree(b->rchild);
free(b);
}
}
int BTHeight(BTNode *b)//求二叉树b的高度
{
int lchildh,rchildh;
if(b==NULL)
return 0;//空树的高度为0
else{
lchildh=BTHeight(b->lchild);//求左子树的高度为lchildh
rchildh=BTHeight(b->rchild);//求右子树的高度为rchildh
return(lchildh>rchildh)?(lchildh+1):(rchildh+1); //比较左右子树高度,选中较大的加一返回
}
}
//输出二叉树数据
void DispBTree(BTNode *b) //以括号表示法输出二叉树
{
if(b!=NULL){
printf("%c",b->data);
if(b->lchild!=NULL||b->rchild!=NULL){
printf("("); //'('递归处理左子树
DispBTree(b->lchild);
if(b->rchild!=NULL) printf(","); //','有右孩子结点时才输出
DispBTree(b->rchild); //递归处理右子树
printf(")");//')'有孩子结点时才输出
}
}
}
再创建一个cpp文件
#include "BTree.cpp" //包含二叉树的基本运算算法
int Nodes(BTNode *b) //求二叉树b的结点个数
{
int num1,num2;
if(b==NULL) return 0;//没有数据0
else if (b->lchild==NULL&&b->rchild==NULL) return 1;//没有左右子树1
else{
num1=Nodes(b->lchild);//记录左子树
num2=Nodes(b->rchild);//记录右子树
return (num1+num2+1);//返回节点个数
}
}
int LeafNodes(BTNode *b)// 求二叉树b的叶子结点个数,基本同上
{
int num1,num2;
if(b==NULL) return 0;
else if (b->lchild==NULL&&b->rchild==NULL) return 1;
else{
num1=LeafNodes(b->lchild);
num2=LeafNodes(b->rchild);
return (num1+num2);
}
}
int Level(BTNode *b,ElemType x,int h)//求二叉树b中结点值为x的结点的层次
{
int i;
if(b==NULL) return(0);//b为空返回0
else if(b->data==x) return(h);//b为叶子节点返回1
else{
i=Level(b->lchild,x,h+1);//在左子树中查找
if(i!=0) return(i);
else return(Level(b->rchild,x,h+1));//在左子树中未找到,再在右子树中查找
}
}
int main(){
ElemType x='6'; BTNode *b;
CreateBTree(b,"W(L(J, 3(Y(O, 4(D, 6(, f))),Q(l,L(,0)))),7");
printf("输出二叉树b:");
DispBTree(b);
printf("\n");
printf("二叉树b的结点个数:%d\n",Nodes(b));
printf("二叉树b的叶子结点个数:%d\n",LeafNodes(b));
printf("二叉树b中值为%c结点的层次:%d\n",x,Level(b,x,1));
printf("二叉树的高度为:%d\n",BTHeight(b));
DestroyBTree(b);
return 1;
}