/**
* 问题描述:
* 根据一颗二叉树的前序和中序遍历结果,重构这颗二叉树并输出后序遍历结果
*/
#include <iostream>
using namespace std;
typedef struct node {
int value;
struct node *left;
struct node *right;
}NODE;
NODE *root;
//节点分配函数
NODE *malloc_NODE(int value){
NODE *p = NULL;
p = (NODE *)malloc(sizeof(NODE));
p->value = value;
p->right = NULL;
p->left = NULL;
return p;
}
/**
* 每次递归根节点已经创建好,我们的任务就是递归创建左子树和右子树
* 从图中可以看到:
* 左子树的前序和中序的起始指针很容易找到,但是右子树的
* 前序和中序的起始指针需要知道左子树的长度才行。
* 此外我们还需要维护一个子树的长度tLen,以便知道当前递归是否应该结束。
*/
void rebuild_tree(NODE *root, //当前子树根节点
int *pre, //当前子树先序序列起始指针
int *in, //当前子树中序序列起始指针
int tLen) //当前子树长度(节点个数)
{
/**
* 首先根据中序序列求出"左子树的长度"和"右子树的长度"
*
* Then:
* 左子树"前序起始点" = 当前前序序列起始点 + 1;
* 左子树"中序起始点" = 当前中序序列起始点;
*
* 右子树"前序起始点" = 当前前序序列起始点 + 左子树长度 + 1;
* 右子树"中序起始点" = 当前中序起始点 + 左子树长度 + 1;
*/
//求出根节点在中序序列中的索引(根据这个索引值求左右子树长度)
int root_value = *pre;
int root_index = 0;
int *p = in;
for(int i=0;i<tLen;i++){
if(*p++ == root_value) break;
root_index++;
}
//求解左子树和右子树的长度
int lLen = root_index;
int rLen = tLen-root_index-1;
//递归左子树
if(lLen != 0){
root->left = malloc_NODE(pre[1]);
rebuild_tree(root->left, pre+1, in, lLen);
}
else{
root->left = NULL;
}
//递归右子树
if(rLen != 0){
root->right = malloc_NODE(pre[lLen+1]);
rebuild_tree(root->right, pre+lLen+1, in+lLen+1, rLen);
}else{
root->right = NULL;
}
}
//前序遍历输出
void printBST(NODE *node){
if(node != NULL){
cout<<node->value<<endl;
printBST(node->left);
printBST(node->right);
}
}
#define M 5
int main(){
int pre[M] = {1,2,4,5,3};
int in[M] = {4,2,5,1,3};
root = malloc_NODE(pre[0]);
//以root为根节点,按照pre和in两个序列重构二叉树
rebuild_tree(root, pre, in, M);
printBST(root);
return 0;
}
分享到:
相关推荐
在IT领域,特别是数据结构和算法的学习中,构建和重构二叉树是一项基本技能。本文将深入探讨如何根据前序序列和中序序列构建二叉树,并使用MFC(Microsoft Foundation Classes)框架来实现图形化输出。对于二叉树的...
在本压缩包“cd.zip_THU OJ_oj_reconfiguration_thu dsa_重构 二叉树”中,主要涉及的是清华大学(THU)在线判题系统(Online Judge,简称OJ)上的一个编程挑战,具体是关于二叉树的重构问题。这个任务涉及到的数据...
分析写一个简单但不失一般性的例子进行分析:返回二叉树:一步递归:前序序列的第一个元素为当前根结点,create根结点。返回值:本级递归创建根结点后,左右孩子指针
二叉树的重建是指根据给定的前序遍历和中序遍历序列重构出原来的二叉树结构。这一过程依赖于二叉树的性质:前序遍历的第一个元素是根节点,中序遍历中根节点左侧的元素构成左子树,右侧的元素构成右子树。通过递归地...
真二叉树重构
3. 给定二叉树的先序和中序遍历结果,如何重构二叉树。 ### 1. 利用先序遍历和层次遍历的结果建立二叉树 在C++中,我们可以定义一个`BinTreeNode`类来表示二叉树中的每个节点,并且定义一个`BinaryTree`类来封装...
此外,还需分析树的遍历结果,并设计算法实现先序和中序遍历(或中序和后序遍历),以重构二叉树。 实验代码包含两个部分。首先,定义了一个`btnode`结构体,其中包含元素数据、左子节点指针和右子节点指针。接着,...
这通常通过递归地遍历树并生成表示树结构的字符串,然后写入文件,或者读取文件内容并重构二叉树实现。 总之,二叉查找树是Java中实现高效数据管理的重要工具。通过理解其基本操作,如创建、插入、查找和删除,以及...
在探讨中,还涉及了如何根据遍历结果重构二叉树的方法,不仅提供了解题思路,还强调了实际操作中的关键步骤和注意事项。 总体来说,本文对二叉树的基本概念、存储方式和遍历方法进行了全面的介绍,并通过实际操作中...
4. 给定二叉树的后序遍历和中序遍历序列,可以利用这些信息重构二叉树并求出前序遍历序列。 5. 通过后序遍历序列和中序遍历序列可以构建出二叉树,然后进行前序遍历以得到前序遍历序列。 理解并掌握这些知识点对于...
类似地,如果给定后序和中序遍历的结果,也可以重构二叉树。在后序遍历中,最后一个元素是根节点,因为它是所有子节点之后访问的。中序遍历仍然可以帮助我们区分左右子树,但是这次我们需要找到根节点右侧的子序列来...
每个题目对应的文档(如`重构二叉树.doc`、`括号编码.doc`等)都提供了详细的题目描述和可能的解答思路。通过实践这些题目,学习者可以深化对C/C++编程语言的理解,提升算法设计和问题解决能力。
之前发布的单独c文件,太大,不可重用,所以我把它重构了,打散成.h和.c文件,加入了Makefile进行编译。 用tar命令解压后,就可以make 运行了。详情请看readme,之前发布的单独文件也在里面
对于A卷的第1题,要求考生编写一个C程序,能够根据给定的二叉树中序和后序遍历序列来重构二叉树,并输出前序遍历序列以及度为0的节点(即叶子节点)的个数。这个题目主要考察了二叉树的遍历和构建方法。首先,中序...
根据给定的遍历序列,我们可以重构二叉树。例如,给定的前序遍历和中序遍历序列可以画出特定的二叉树结构。 5. **图的遍历**:图的深度优先遍历(DFS)和广度优先遍历(BFS)是两种重要的遍历方法。DFS通常从一个...
3. 重构二叉树:当达到一定的重构条件(如符号出现次数或时间间隔)时,基于当前权重重新构造二叉树。 4. 生成码字:使用新树结构为每个符号生成码字。 5. 输出编码结果:将生成的码字输出,形成压缩后的数据流。 `...
根据给定的遍历序列,我们可以重构二叉树的形态。 算法是解决问题的精确步骤描述,具有可行性、确定性、有穷性和拥有足够的情报等特性。算法的时间复杂度和空间复杂度分别描述了算法运行所需的计算时间和内存空间。...
根据两种遍历序列可以重构二叉树。 第三部分介绍了图的存储方法,包括邻接矩阵和邻接表,以及十字链表。图的遍历包括深度优先搜索和广度优先搜索,生成树和最小生成树是图的基本操作。拓扑排序需要无环的有向图,...
根据这两个序列,我们可以重构二叉树的先序序列(preorder traversal),即从根节点开始,然后遍历左子树,最后遍历右子树。正确答案是 B:E、A、C、B、D、G、F。这道题考察了二叉树的三种遍历方法的理解和应用。 ...
14. 给定后序和中序遍历,可以重构二叉树,这里先序遍历是`cedba`。 15. 在线索二叉树中,结点是叶子结点当且仅当左右线索都为1。 16. 二叉树的性质表明,度为1的结点3个,度为2的结点4个,叶子结点数为5。 17. 权值...