二叉树实验报告

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

二叉树实验报告

问题描述

(1)问题描述:①用先序递归过程建立二叉树(存储结构:二叉链表)。

输入数据按先序遍历所得序列输入,当某结点左子树或右子树为空时,输入‘*’号,如输入abc**d**e**得到的二叉树为:

②编写递归算法,计算二叉树中叶子结点的数目。

③按凹入表方式输出该二叉树。

(2)分析:①此题要求用二叉链表作为存储结构,首先要定义二叉链表:

typedef struct BiTNode {

char data;

struct BiTNode *lchild, *rchild;

}BiTNode, * BiTree;

struct BiTNode *lchild, *rchild中lchild,rchild分别表示该结点的左右孩子。

②输入时,按先序遍历所得序列输入,当某结点左子树或右子树为空时,输入‘*’号。

③输出以凹入表的形式输出。

算法思想

(1)按照要求,这道题采用二叉链表来存储矩阵的有关信息。

存储结构定义为:

typedef struct BiTNode {

char data;

struct BiTNode *lchild, *rchild;

}BiTNode, * BiTree;

题中共有四个函数,包括主函数main(),创建二叉树函数Status preorder(BiTree &T),计算叶子结点函数Status calLeaf(BiTree &T),输出函数Status output(BiTree &T,int)。其中,主函数首先调用preorder()创建二叉树,然后调用函数calLeaf()。最后调用函数output(),输出二叉树。

(2)算法描述:

main()

{

BiTree T;

int depth = 0;

// 打印提示语

//输入先序序列

preorder(T);//调用函数,先序创建二叉树

calLeaf(T);//调用函数calLeaf()计算叶子结点数并打印

output(T,depth);//调用函数凹入输出

system("pause");

return 0;

}

//创建

Status preorder(BiTree &T)

{

char ch;

scanf("%c",&ch);//读入数据

if(ch == '*')

T=NULL; //读到*号,表明该结点无孩子

else{

if ( ! (T=(BiTNode *)malloc(sizeof(BiTNode))) )//动态申请

exit(OVERFLOW);

T->data=ch;//将数据计入结点的数据域

//递归调用

}

}//CreatBiTree

//计算叶子结点数

Status calLeaf(BiTree &T)

{

if(空树,无叶子)

return ERROR;

else if(只有左孩子或右孩子)

return 1; /

else

递归调用

}

Status output(BiTree &T,int depth)

{

int i;

if(当前结点不为空){

depth ++;//深度加1

//打印元素前空格

//打印数据

if (左孩子)

if (! output(T->lchild,depth)) return ERROR;//递归if (右孩子)

if (! output(T->rchild,depth) ) return ERROR;//递归

return OK;

}

else return ERROR;

}

源程序

已提交

测试结果

(1)用户使用说明:

①运行环境:visual C++ 6.0

Dev-c++

②程序启动:Ctrl+F10

③操作步骤:按照提示输入

④输入:abc**d**e**

图1

打印提示语,运行正常。

按要求输入先序遍历序列,按该序列得到的二叉树为图1所示二叉树,叶子结点数为3,a 在第一层,b,e在第二层,c,d在第三层。运行正常。

心得体会

(1)Status calLeaf(BiTree &T)

{

if(!T)

return ERROR; //空树,无叶子

else {

if(!(calLeaf(T->lchild)))

num ++;

else if(!(calLeaf(T->lchild)))

num ++;//递归调用

}

return num;

}

这种算法的思想是递归调用函数,当调用到没有孩子的叶子结点时,num数加1。这样依次计算,最终找到所有的叶子结点。

但是,这种算法在调用时,不能统计右子树上的叶子结点,导致出现下面的错误:

所以改成了现在的算法:

Status calLeaf(BiTree &T)

{

if(!T)

return ERROR; //空树,无叶子

else if(!T->lchild && !T->rchild)

return 1; //只有左孩子或右孩子

else

return (calLeaf(T->lchild) + calLeaf(T->rchild));//递归调用 }

当T为空时,是空树,叶子结点数为0;当左孩子或右孩子有一个不存在时,叶子结点数为1;当左右孩子都存在时,递归调用,知道找到所有的叶子结点,返回左右子树上叶子结点数之和即为所求。

(2)心得体会:这道题用二叉链表存储二叉树,二叉链表由数据元素,左孩子指针和右孩子指针组成。用二叉链表存储二叉树比较简单,但是不足是不能存储该节点的双亲,这种情况下,用线序序列建立二叉树比较方便。虽然是用二叉链表这种较为简单的方式存储二叉树,但对于初次接触树的概念的我还是一个很好的锻炼机会,增强了对于二叉树孩子与双亲的关系的理解,有助于更好的了解二叉树的结构。

输入数据后,循环调用创建函数,依次读入数据并保存。创建二叉树,计算叶子结点数和打印凹入表都要用到递归函数。可以说,对树和操作都主要是对递归函数的调用,复习了对二叉链表的应用。对于递归算法,现在的理解一直比较模糊,通过这道题在一定程度上增加了对递归函数的理解。

选做

(1)用先序和中序遍历建立二叉树。用户分别输入一个二叉树的先序遍历序列和中序遍历序列,通过两个遍历序列建立二叉树。

(2)解决方法:二叉树存储方式不变,但在程序中增加两个字符数组pre[]和in[]分别用于存放两个遍历序列。用递归的算法解决问题。不难发现,pre[]中的第一个元素即为根节点对应的元素。而在in[]数组中,若第i个元素等于pre[0],那么从第一个到第i-1个元素即为根节点的左子树。按照这个方法,用递归的算法即可构建一棵完整的二叉树。

相关文档
最新文档