一、实验目的
1.理解二叉树的类型定义与性质。
2.掌握二叉树的二叉链表存储结构的表示和实现方法。
3.掌握二叉树遍历操作的算法实现。
4.熟悉二叉树遍历操作的应用。
二、实验内容
1.建立二叉树的二叉链表存储结构。
2.实现二叉树的先序、中序和后序三种遍历操作。
3.应用二叉树的遍历来实现判断两棵二叉树是否相等的操作。(选做)
三、实验要求
1.建立二叉树的二叉链表存储结构。
假设二叉树的结点值是字符,根据输入的一棵二叉树的先序遍历序列建立以二叉链表表示的二叉树。
2.实现二叉树的先序、中序和后序三种遍历操作。
对上述内容1中建立的二叉树进行先序、中序和后序遍历操作,并输出遍历序列,观察输出的序列是否与逻辑上的序列一致。
3.应用二叉树的遍历来实现判断两棵二叉树是否相等的操作。(选做)
(1)假设二叉树的结点值是字符,分别根据输入的两棵二叉树的某一遍历序列建立二叉链表表示的两棵二叉树。
(2)利用任一种遍历方法实现对两棵树是否相等的判断。
四、详细程序清单
//1.二叉树的先序建立和三种遍历
#include<stdio.h>
#include<stdlib.h>
//链式结构
typedef struct BiTNode {
char data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
int CreateBiTree(BiTree &T)//先序建立二叉树
{
char ch;
scanf("%c",&ch);
if(ch=='*') T=NULL;
else
{
if(!(T=(BiTNode*)malloc(sizeof(BiTNode))))
{
printf("内存分配失败\n");
exit(0);
}
T->data=ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
}
void PreorderTraverse(BiTree T)//先序遍历的递归算法
{
if(T)
{
printf("%c",T->data);
PreorderTraverse(T->lchild);
PreorderTraverse(T->rchild);
}
}
void InorderTraverse(BiTree T)//中序遍历
{
if(T)
{
InorderTraverse(T->lchild);
printf("%c",T->data);
InorderTraverse(T->rchild);
}
}
void PostorderTraverse(BiTree T)//后序遍历
{
if(T)
{
PostorderTraverse(T->lchild);
PostorderTraverse(T->rchild);
printf("%c",T->data);
}
}
int main()
{
BiTree T;
printf("先序建立二叉树,输入结点的值,*表示结点为空\n");
CreateBiTree(T);//创建
printf("先序遍历结果:");
PreorderTraverse(T);//先序
printf("\n中序遍历结果:");
InorderTraverse(T);//中序
printf("\n后序遍历结果:");
PostorderTraverse(T);//后序
return 0;
}
//2.判断两棵二叉树是否相等
#include<stdio.h>
#include<stdlib.h>
//链式结构
typedef struct BiTNode {
char data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;
int flag=1;//定义全局变量,用于退出递归
int CreateBiTree(BiTree &T)//先序建立二叉树
{
char ch;
scanf("%c",&ch);
if(ch=='*') T=NULL;
else
{
if(!(T=(BiTNode*)malloc(sizeof(BiTNode))))
{
printf("内存分配失败\n");
exit(0);
}
T->data=ch;
CreateBiTree(T->lchild);
CreateBiTree(T->rchild);
}
}
int Equal2(BiTree T1,BiTree T2)//利用先序遍历判断两棵二叉树是否相等.
{
if(flag==0) return 0;
if(T1==NULL&&T2==NULL)
{
flag=1;
return flag;
}
else if(T1==NULL||T2==NULL)
{
flag=0;
return flag;
}
else
{ if(T1->data==T2->data) flag=1;
else flag=0;
if(flag)
{
Equal2(T1->lchild,T2->lchild);
Equal2(T1->rchild,T2->rchild);
}
}
}
int main()
{
BiTree T1,T2;
printf("先序建立二叉树,输入结点的值,*表示结点为空\n");
printf("树1:");
CreateBiTree(T1);//创建树1
getchar();
printf("树2:");
CreateBiTree(T2);//创建树2
flag=Equal2(T1,T2);
if(flag)
printf("相同");
else printf("不同");
return 0;
}
五、程序运行结果
1. 二叉树的先序建立和三种遍历 :
2. 判断两棵二叉树是否相等:
六、实验心得体会
1. 通过本次作业,加深了对递归的理解,掌握了递归的用法。
2. 对于实验三:判断两棵二叉树是否相等。当判断到字符不同时,由于是递归函数,不能只用简单的return 0;退出函数,因为这样只会退到上一层函数。解决方法:定义一个全局变量flag,初始值为1,当判断到字符不同时令flag=0;在判断函数Equal2中加上判断:if(flag==0) return 0;由于flag是全局变量,每一层Equal2函数中的flag都会变为0,所以可以完全退出递归。
3.在实验三中遇到了一个奇怪的问题:建立的两个二叉树明明一样,却无法执行下一步,第二棵树必须多输入一个*才可以,然而判断的结果是错误的。如下:
后来发现是scanf缓存区的问题,建立树1后的回车键也占一个字符(因为之前作业没有scanf过字符型变量,所以没有遇到过这个问题),比如想建立一个A**,却建立了一个\nA***,如下:
正确的 错误的
解决方法:在建立树1后用fflush(stdin);清空缓存区,或加上getchar();来保存‘\n’。