二叉树(14)----由前序遍历和中序遍历重建二叉树

1、二叉树定义

typedef struct BTreeNodeElement_t_ {
    void *data;
} BTreeNodeElement_t;

typedef struct BTreeNode_t_ {
    BTreeNodeElement_t     *m_pElemt;
    struct BTreeNode_t_    *m_pLeft;
    struct BTreeNode_t_    *m_pRight;
} BTreeNode_t;

二、根据前序遍历序列和中序遍历序列重建二叉树

算法说明:

由中序遍历序列可知,第一个节点是根节点,

由前序遍历序列可知,第一个节点是根节点的左子树节点,而且前序遍历中,根节点左边是左子树,右边是右子树,因此通过中序遍历的根节点可以确定的是:

根节点在前序遍历中的位置(通过遍历中序遍历序列比较可知);

左子树的节点数,因为一旦找到前序遍历中根节点的位置,就找到左右子树的分界点,也就是说,前序遍历中根节点左边的都是左子树节点,可以通过遍历知道左子树的节点数;

同样,右子树的节点数也可以确定。

通过以上确定的信息,可以划分出前序遍历中的左右子树节点数,根节点位置。

通过递归可以求得整个树的结构。

BTreeNode_t  * RebuildBTree( const BTreeNodeElement_t *pPreorder,
                             const BTreeNodeElement_t *pInorder,
                             const int nodesTotal,
                             int(*compare)(const BTreeNodeElement_t*, const BTreeNodeElement_t *)){
    if( pPreoder == NULL || pInorder == NULL || nodesTotal <= 0 || compare == NULL)
        return NULL;

    BTreeNodeElement_t *pRootData = pInorder[0];  //找到当前树的根节点
    BTreeNode_t *pRoot= new  BTreeNode_t;
    pRoot->m_pElemt = pRootData;

    int rootIndex = -1;
    for( int i = 0; i < nodesTotal; ++i){
        if( compare( pRootData, pPreorder[i]) == 0){
            rootIndex = i;
            brea;
        }
    }
    if( rootIndex == -1 )
        return NULL;

//根据查找到根节点得到的信息,左子树长度,右子树长度等
    int leftNodesTotal = rootIndex;
    BTreeNodeElement_t *pLeftPreorder = pPreorder + 1;
    BTreeNodeElement_t *pLeftInorder = pInorder;
    pRoot->m_pLeft = RebuildBTree( pLeftPreorder, pInorder, leftNodesTotal, compare);

//右子树信息
    int rightNodesTotal = nodesTotal - leftNodesTotal - 1;//减去右子树节点数和一个根节点
    BTreeNodeElement_t *pRightPreOrder = pPreorder + leftNodesTotal + 1;
    BTreeNodeElement_t *pRightInorder = pInorder + leftNodesTotal + 1;
    pRoot->m_pRight = RebuildBTree( pRightPreOrder, pRightInorder, rightNodesTotal, compare);

    return pRoot;
}
				
时间: 2024-08-07 08:37:36

二叉树(14)----由前序遍历和中序遍历重建二叉树的相关文章

线索二叉树实例(前序创建,中序遍历)--2018.5.15

#include <stdio.h> #include <stdlib.h> #define ERROR 0 #define OK 1 typedef enum{Link, Thread} PointerTag; //link = 0表示指向左右孩子指针 //Thread = 1表示指向前驱或后继的线索 typedef struct BitNode { char data; //结点数据 struct BitNode *lchild; //左右孩子指针 struct BitNode

根据二叉树的前序遍历和中序遍历重建二叉树

题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回. 1 /** 2 * Definition for binary tree 3 * struct TreeNode { 4 * int val; 5 * TreeNode *left; 6 * TreeNode *right; 7 * TreeNode(

题目:输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树

问题描述: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回. 思路: 在二叉树的前序遍历序列中,第一个数字总是树的根结点的值.但在中序遍历序列中,根结点的值在序列的中间,左子树的结点的值位于根结点的值的左边,而右子树的结点的值位于根结点的值的右边.因此我们需要扫描中序遍历序列,才能找到根结点的值. 如下图所示,

二叉树、前序遍历、中序遍历、后序遍历

一.树 在谈二叉树前先谈下树和图的概念 树:不包含回路的连通无向图(树是一种简单的非线性结构) 树有着不包含回路这个特点,所以树就被赋予了很多特性 1.一棵树中任意两个结点有且仅有唯一的一条路径连通 2.一棵树如果有n个结点,那它一定恰好有n-1条边 3.在一棵树中加一条边将会构成一个回路 4.树中有且仅有一个没有前驱的结点称为根结点 在对树进行讨论的时候将树中的每个点称为结点, 根结点:没有父结点的结点 叶结点:没有子结点的结点 内部结点:一个结点既不是根结点也不是叶结点 每个结点还有深度,比

已知二叉树的前序遍历、中序遍历或者中序遍历、后序遍历求二叉树结构的算法

二叉树中的前序遍历是先访问根结点,再访问左子树,右子树. 中序遍历是先访问左子树,再是根结点,最后是右子树. 后序遍历是先访问左子树,再是右子树,最后是根结点. 算法思路是先根据前序遍历的第一个结点或者后序遍历的最后一个结点,查找对应在中序遍历中的位置,就可以确定左子树包含的元素和右子树包含的元素,最后通过递归来实现就可以了. 二叉树的表示形式为 //二叉树的结构表示为 class TreeNode { int val; TreeNode left; TreeNode right; TreeNo

输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

问题描述: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.假设输入的前序遍历和中序遍历的结果中都不含重复的数字.例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回. 思路: 在二叉树的前序遍历序列中,第一个数字总是树的根结点的值.但在中序遍历序列中,根结点的值在序列的中间,左子树的结点的值位于根结点的值的左边,而右子树的结点的值位于根结点的值的右边.因此我们需要扫描中序遍历序列,才能找到根结点的值. 如下图所示,

前序遍历和中序遍历重建二叉树

对于二叉树,在此我不做过多讲解,如有不懂,请参照一下链接点击打开链接 1.在此二叉树的定义: struct BinaryTreeNode     {         BinaryTreeNode<T> *_Left;         BinaryTreeNode<T> *_Right;         T _data;     public:         BinaryTreeNode(const T& x)             :_Left(NULL)       

已知二叉树的前序遍历和中序遍历,如何得到它的后序遍历?

对一棵二叉树进行遍历,我们可以采取3中顺序进行遍历,分别是前序遍历.中序遍历和后序遍历.这三种方式是以访问父节点的顺序来进行命名的.假设父节点是N,左节点是L,右节点是R,那么对应的访问遍历顺序如下: 前序遍历    N->L->R 中序遍历    L->N->R 后序遍历    L->R->N /***************************************************************************************

027依据前序遍历和中序遍历,重建二叉树(keep it up)

剑指offer中题目:http://ac.jobdu.com/problem.php?pid=1385 题目描写叙述: 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树.如果输入的前序遍历和中序遍历的结果中都不含反复的数字. 比如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并输出它的后序遍历序列. 输入: 输入可能包括多个測试例子,对于每一个測试案例, 输入的第一行为一个整数n(1<=n<=1000):代表二叉树的节点

二叉树的遍历规则(前序遍历、后序遍历、中序遍历)

今天看了一些关于平和查找二叉树的问题,顺便也复习了一下二叉树的遍历规则,写一下学习文档. 树的遍历顺序大体分为三种:前序遍历(先根遍历.先序遍历),中序遍历(中根遍历),后序遍历(后根遍历). 如图所示二叉树: 前序遍历:前序遍历可以记为根左右,若二叉树为空,则结束返回. 前序遍历的规则: (1)访问根节点 (2)前序遍历左子树 (3)前序遍历右子树 这里需要注意:在完成第2,3步的时候,也是要按照前序遍历二叉树的规则完成. 前序遍历的输出结果:ABDECF 中序遍历:中序遍历可以记为左根右,也