根据先序和中序序列构建二叉树

说明:

本次实验利用中序和先序序列,采用递归方式来构建二叉树 。

经过几天的失败和思考,我认为递归构建二叉树的过程中最重要的是递归单元,最麻烦的是递归参数的选择和传递。

简单将算法过程用如下流程图来表示:(本帖所用算法及图片均为原创内容,转贴注明出处)

算法:1.根据先序序列,建立根结点T

2.寻找中序序列的根结点位置,并据此位置计算左子树和右子树的区间

3.判断l_start和r_end是否相等,相等则表示只有一个根结点,设置其左右孩子结点为空并结束这一层;若不相等则继续下面步骤:

4.根据2中的左孩子区间,若区间不空,递归调用函数自身;若区间为空则令其左孩子为空;

5.根据2中的右孩子区间,若区间不空,递归调用函数自身;若区间为空则令其右孩子为空;

代码实现如下:

 1 //6.根据先序和中序序列构建二叉树
 2 typedef int ElemType;
 3 typedef int Status;
 4
 5 typedef struct BTNode{
 6     ElemType    data;
 7     struct BTNode *lchild,*rchild;
 8 }BTree;
 9 int Pre[7]={1,2,3,4,5,6,7},In[7]={3,2,4,1,6,5,7};
10 int preRoot=0;
11 Status CreByPreIn(BTree *root,int l_start,int r_end){
12     int nowpos=0;
13     root->data=*(Pre+preRoot);
14     while(*(In+nowpos)!=root->data)nowpos++;
15     preRoot++;
16     if(l_start == r_end){
17         root->lchild=NULL;
18         root->rchild=NULL;
19         return OK;
20     }
21     if(l_start<=nowpos){
22         BTree *lt=(BTree*)malloc(sizeof(BTree));
23         root->lchild=lt;
24         CreByPreIn(root->lchild,l_start,nowpos-1);
25     }
26     else root->lchild=NULL;
27     if(nowpos<=r_end){
28         BTree *rt=(BTree*)malloc(sizeof(BTree));
29         root->rchild=rt;
30         CreByPreIn(root->rchild,nowpos+1,r_end);
31     }
32     else root->rchild=NULL;
33 }

感想:对于这个算法,最困扰我的就是递归的参数传递问题,因为是编程之前接触的少,递归也算是第一次自己写,所以走了很多弯路。

我的收获就是,编写程序之前一定要先设计好算法的流程,最好能够将算法需要用到的参数,变量,函数名都预先写好,这样更有利于算法转化为代码实现。

理解递归,多参考一下别人的经验吧,带图的最好了,不带图的都是耍流氓。

欢迎大家和我交流,相互学习。

时间: 2024-11-21 02:59:54

根据先序和中序序列构建二叉树的相关文章

Leetcode:Construct Binary Tree 前序和中序、后序和中序构建二叉树

前序和中序构建二叉树 后序和中序构建二叉树 分析:主要思路就是 在中序中找根节点然后划分左右子树,具体如下: 1. 查找根节点. 我们知道前序序列的第一个元素 和 后序序列的最后一个元素 肯定是根节点,我们就以此为突破口 2. 确定根节点的坐标. 我们在 中序序列中找到 根节点 的下标. 3. 分割左右子树. 对于中序序列:根节点下标之前的都属于左子树,之后的都属于右子树 对于先序序列:根节点之后的 一段元素(该段长度可以由中序序列的左子树长度确定)属于左子树,左子树之后的元素属于右子树 对于先

给定二叉树先序、中序遍历序列,求后序遍历

给定一个二叉树的前序遍历和中序遍历的序列,输出对应这个二叉树的后续遍历序列. 输入描述: 输入为一行. 两个字符串,分别表示二叉树的前序遍历和中序遍历结果,用空格分隔.保证数据合法 输出描述: 对应输出后序遍历序列 示例1 输入 ABDEC DBEAC 输出 DEBCA思路:先根据先序.中序序列建立二叉树,然后后序遍历 import java.util.Scanner; import javax.print.attribute.standard.PresentationDirection; cl

如何由二叉树的先序和中序序列画出二叉树

今天数据结构的考试有这个题,做了好久,下来后,我好好地在网上查了一下,并结合我自己的理解,总结出来了一个比较好理解的方法.这个方法可以说做起这样的题又快又准. (概括为一个口诀:先序放中间,中序分两边)  基本思想就是递归:1.取出先序的第一个节点.(先序中的节点为根节点)2.用第一个节点可以将中序分成左右子树,然后又取出先序的第二个节点   再次将左右子树再次划分,3,当将中序全部划分为单个点时就结束.例如:假设一颗二叉树的先序序列是:EBADCFHGIKJ. 中序序列为:ABCDEFGHIJ

通过树的先序和中序遍历序列来构造二叉树

题目:给出一棵二叉树的先序和中序遍历的序列,构造出该二叉树. 思路一:采用分治法. 1)取先序遍历序列的第一个值,用该值构造根结点,,然后在中序遍历序列中查找与该元素相等的值,这样就可以把序列分为三部分:左子树(如果有).根结点和右子树(如果有). 2)将两个序列都分成三部分,这样就分别形成了根结点的左子树和右子树的先序遍历和后序遍历的序列. 3)重复1)和2)步骤,直至所有结点都处理完就可以完整构成一颗二叉树了. 根据分治法构造二叉树的代码实现: TreeNode *buildTree(vec

算法进化历程之“根据二叉树的先序和中序序列输出后序序列”

巧若拙(欢迎转载,但请注明出处:http://blog.csdn.net/qiaoruozhuo) 前不久在看到一个作业"根据二叉树的先序和中序序列输出后序序列",当时我参考<数据结构与算法(C语言)习题集>上的做法,先根据先中序序列确定一颗二叉树,然后后序遍历二叉树输出后序序列. 函数采用了递归算法,利用函数传入的先序和中序序列的左右边界,确定要处理的序列段,生成相应的二叉树. 基本思路是,把该段先序序列的第一个元素作为当前二叉树的根结点,然后在中序序列找到根结点.根结点

根据先序遍历中序遍历重建二叉树

根据先序遍历和中序遍历的特点,我们想到了采用递归的方法来实现. 思路:1) 代码的容错性检查,比如:先序遍历和中序遍历长度应相等 2) 先保存先序遍历的第一个点,这个点为结点,接下来循环中序遍历,直到midOrd[index]=该结点,那么接下来就可以采用递归,分别对结点左边和右边的序列采用相同的方法. 3) 直到中序遍历中的序列中只含一个点,整个过程结束. 下面是我写的代码,一直显示错误,不知道什么原因. // 先序中序重建二叉树.cpp : Defines the entry point f

Tree Recovery(由先、中序列构建二叉树)

题目来源: http://poj.org/problem?id=2255 题目描述: Description Little Valentine liked playing with binary trees very much. Her favorite game was constructing randomly looking binary trees with capital letters in the nodes. This is an example of one of her cr

二叉树遍历 ——已知后序,中序求层序 A1020.(25)

若直接DFS递归求解,会栈溢出 #include <cstdio> #include <cstring> #include <queue> #include <algorithm> using namespace std; const int maxn=50; struct node{ int data; node* lchild; node* rchild; }; int pre[maxn],in[maxn],post[maxn];//先序,中序,后序 i

先序+中序和中序+后序建树

思路:先序的第一个元素和后序的最后一个元素是当前子树的根,然后遍历中序序列,找到左右子树的分界线,递归建左子树和右子树. class Solution { public: /*由于是oj,这里假设给的序列是合法的,正常情况是需要判断不合法情况的 */ TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder,int instart,int inend,int poststart,int post