实习三 二叉树及其应用

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

实习三树、二叉树及其应用
题目:唯一地确定一棵二叉树实习时间:2012/10/30
一、需求分析
1.问题描述:如果给出了遍历二叉树的前序序列和中序序列,则可以构造出唯一的一棵二叉树。

试编写实现上述功能的程序。

2.基本要求: 已知一棵二叉树的前序和中序序列,试设计完成下列任务的一个
算法:
(1)构造一棵二叉树;
(2)证明构造正确(即分别以前序和中序遍历该树,将得到的结
果与给出的序列进行比较)。

3.测试数据: 前序序列为ABDEGCFHIJ,中序序列为DBGEAHFIJC。

二、设计
二、 1. 设计思想
二、(1)存储结构
二、用两个一维数组A和B分别存放前序和中序序列。

(2)主要算法基本思想
①将前序和中序序列分别读入数组A和B。

②根据定义,前序序列中第一个元素一定是树根,在中序序列中该
元素之前的所有元素一定在左子树中,其余元素则在右子树中。

所以,
首先从数组A中取出第一个元素A[0]作根结点,然后在数组B中找到A[0],
以它为界,在其前面的是左子树中序序列,在其后面的是右子树中序序列。

③若左子树不为空,沿前序序列向后移动,找到左子树根结点,转②。

④左子树构造完毕后,若右子树不为空,沿前序序列向后移动,找到
右子树根结点,转②。

⑤前序序列中各元素取完则二叉树构造完毕。

⑥对二叉树进行前序和中序遍历,并将结果分别与数组A和B进行
比较,若相同,则证明二叉树构造正确。

2. 设计表示
(1)函数调用关系图
main→StackPush→QueueAppend→QueueAd→StackPop→QueueGet
(2)函数接口规格说明
void PrintTree(BiTreeNode root,int n) //以root为根节点的树凹形输出
void Initiate(BiTreeNode *root) // 以root为根节点的树初始化
void PreOrder(BiTreeNode bt) //前序遍历以bt为根结点指针的二叉树
void InOrder(BiTreeNode bt) //中序遍历以bt为根结点指针的二叉树
int Creattree(DataType *pre,DataType *in,int al,BiTreeNode &T) //用前序序列和中序序列构造以T 为根节点的树,其中pre,in分别为前序序列和中序序列的首地址,al为中序序列的长度。

3. 实现注释(即各项功能的实现程度)
(1)必须正确输入前序序列和中序序列;
(2)若前序序列和中序序列的长度不一样,则输出“不匹配”;
(3)若前序序列和中序序列的长度一样,但不能构成一棵二叉树,则程序会出错,即程序缺乏健壮性。

4. 详细设计(即主要算法的细化。

略,见上课笔记)
【1】void Initiate(BiTreeNode *root) // 树的初始化
{
*root=(BiTreeNode)malloc(sizeof(struct Node));
(*root)->leftChild=NULL;
(*root)->rightChild=NULL;
}
【2】int Creattree(DataType *pre,DataType *in,int al,BiTreeNode &T)
{ //树的创建
int k;
DataType *i;
if(al<=0)
{
T=NULL;
return 0;
}
for(i=in;i<in+al;i++) //查找根结点
if(*pre==*i)
{
k=i-in; //k为根结点在中序序列中相对头结点的距离
T=(BiTreeNode)malloc(sizeof(struct Node));
T->data=*i;
break;
};
Creattree(pre+1,in,k,T->leftChild); //建立左子树
Creattree(pre+k+1,in+k+1,al-k-1,T->rightChild);//建立右子树
}
【3】void PrintTree(BiTreeNode root,int n) //树的凹形输出
{
int i;
if(root==NULL)return;
PrintTree(root->rightChild,n+1);
for(i=0;i<n-1;i++)printf(" ");
if(n>0)
{
printf("---");
printf("%c\n",root->data);
}
if(n==0)
{
printf("-");
printf("%c\n",root->data);
}
PrintTree(root->leftChild,n+1);
}
【4】void PreOrder(BiTreeNode bt) //前序遍历以bt为根结点指针的二叉树
{
if (bt==NULL) return;
printf("%c",bt->data);
PreOrder(bt->leftChild);
PreOrder(bt->rightChild);
}
【5】void InOrder(BiTreeNode bt) //中序遍历以bt为根结点指针的二叉树
{
if (bt==NULL) return;
InOrder(bt->leftChild);
printf("%c",bt->data);
InOrder(bt->rightChild);
}
三、调试分析
1.调试过程中遇到的主要问题是如何解决的;
调试过程中存在少许C语言的基础语法错误,经独立仔细观察和调试修改正确,最大的难题是创建树时,递归调用自身函数的中序序列数组下标表示。

在自己独立多次修改下,终于完成。

2.对设计和编码的回顾讨论和分析;
总的来说,这个程序写的比较顺畅,毕竟老师已经把整个算法思路都已给出。

但是,每次写程序都有的感觉是,对好多的基本语法还不是特别熟悉,写到某些刚学的数据结构知识时得在书中找代码和代码思想。

所以,应该多练习才好。

3.时间和空间复杂度的分析;
【1】创建二叉树的函数:时间O(n),空间O(n)
【2】二叉树的凹形输出函数:时间O(n),空间O(1)。

4.改进设想;
【1】在递归创建二叉树的算法中,若能判断前序序列和中序序列是否能构成二叉树,这样就能增强程序的健壮性。

向同学请教过,也找了部分电子和书本知识,但均未发现解决办法。

【2】重新设计创建二叉树的非递归算法,这样能较好的解决程序的健壮性问题。

但非递归算法过程较复杂。

5.经验和体会等。

多动手编程,才能熟练灵活的掌握C语言基础知识,才能更好的理解掌握数据结构的精髓。

从而避免基础语法错误,让代码变得更简洁高效。

如此才能准确高效的解决问题。

在今后的编程过程中要更注重代码整体设计的提纲记录,用更多的注释。

四、用户手册(即使用说明)
仅需按照提示正确输入前序序列和中序序列。

若出错,则表明前序序列和中序序列不能构成一颗二叉树。

五、运行结果
运行环境:C-free
【1】前序序列为ABDEGCFHIJ,中序序列为DBGEAHFIJC。

【2】前序序列为ABC,中序序列为BAC。

【3】前序序列为ABCEFDGH,中序序列为ECFBGDHA。

【4】若长度不一:前序序列为ABDEGCFHIJ,中序序列为DBGEAHFIJCZ。

【5】若前序序列和中序序列的长度一样,但不能构成一棵二叉树。

前序序列为ABC,中序序列为CAB。

【6】若前序序列和中序序列的长度一样,但不能构成一棵二叉树。

前序序列为ABC,中序序列为GHJ。

六、源程序清单
见文库文本文件“树、二叉树及其应用-唯一地确定一棵二叉树”。

相关文档
最新文档