重构二叉树

转载 2016年05月31日 10:44:29

对于一颗二叉树,可以根据先序遍历(后序遍历)和中序遍历重新还原出二叉树。

根据先序遍历和中序遍历还原二叉树的主要思想:

1、先序遍历序列的第一个元素必定是根节点,可以由此获取二叉树的根节点。

2、根据根节点,在中序遍历序列中查找该节点,由中序遍历的性质可知,中序遍历中该根节点左边的序列必定在根节点的左子树中,而根节点右边的序列必定在右子树中。由此可以知道先序遍历中左子树以及右子树的起止位置。

3、分别对左子树和右子树重复上述的过程,直至所有的子树的起止位置相等时,说明已经到达叶子节点,遍历完毕。

代码如下:

#ifndef __FUNCTION_H__
#define __FUNCTION_H__
#include <iostream>


using namespace std;
struct BinaryTreeNode
{
    int nodeValue;
    BinaryTreeNode *pLeft;
    BinaryTreeNode *pRight;
};


BinaryTreeNode * BuildRecursivly(int *pPrevOrderStart, int *pPrevOrderEnd, int *pInOrderStart, int *pInOrderEnd)
{
    //在先序遍历序列中取出第一个元素即为根节点元素
    int value = pPrevOrderStart[0];
    //构造根节点
    BinaryTreeNode *root = new BinaryTreeNode;
    root->nodeValue = value;
    root->pLeft = root->pRight = NULL;
    //递归结束的情况,即只剩一个叶子节点
    if(pPrevOrderStart == pPrevOrderEnd)
    {
        if(pInOrderStart == pInOrderEnd && *pPrevOrderStart == *pInOrderStart)
            return root;
        else
            throw std::exception();
    }
    //在中序遍历序列中找出根节点的位置
    int *pInOrderCursor = pInOrderStart;
    while(pInOrderCursor < pInOrderEnd && *pInOrderCursor != value)
    {
        pInOrderCursor++;
    }
    if(pInOrderCursor == pInOrderEnd && *pInOrderCursor != value)
    {
        throw std::exception();
    }
    //取得左子树的长度以及在先序遍历中取得左子树的起始位置
    int leftTreeLen = pInOrderCursor - pInOrderStart;
    int *pPrevOrderLeftTreeEnd = pPrevOrderStart + leftTreeLen;
    //如果左子树存在,则递归左子树
    if(leftTreeLen > 0)
    {
        root->pLeft = BuildRecursivly(pPrevOrderStart+1, pPrevOrderLeftTreeEnd,
                                      pInOrderStart, pInOrderCursor-1);
    }
    //如果右子树存在,则递归右子树
    if((pPrevOrderEnd-pPrevOrderStart) > leftTreeLen)
    {
        root->pRight = BuildRecursivly(pPrevOrderLeftTreeEnd+1, pPrevOrderEnd,
                                       pInOrderCursor+1, pInOrderEnd);
    }


    return root;
}


BinaryTreeNode * BulidBinaryTree(int *szPrevOrder, int *szInOrder, int nodeNum)
{
    if(szPrevOrder == NULL || szInOrder == NULL)
        return NULL;
    return BuildRecursivly(szPrevOrder, szPrevOrder+nodeNum-1,
                           szInOrder, szInOrder+nodeNum-1);
}


/*先序遍历*/
void PrevOrder(BinaryTreeNode *root)
{
    if(root == NULL)
        return;
    //根
    cout<<root->nodeValue<<' ';
    //左子树
    if(root->pLeft != NULL)
        PrevOrder(root->pLeft);
    //右子树
    if(root->pRight != NULL)
        PrevOrder(root->pRight);
}


/*中序遍历*/
void InOrder(BinaryTreeNode *root)
{
    if(root == NULL)
        return;
    //左子树
    if(root->pLeft != NULL)
        InOrder(root->pLeft);
    //根
    cout<<root->nodeValue<<' ';
    //右子树
    if(root->pRight != NULL)
        InOrder(root->pRight);
}


/*后序遍历*/
void PostOrder(BinaryTreeNode *root)
{
    if(root == NULL)
        return;
    //左子树
    if(root->pLeft != NULL)
        PostOrder(root->pLeft);
    //右子树
    if(root->pRight != NULL)
        PostOrder(root->pRight);
    //根
    cout<<root->nodeValue<<' ';
}


#endif


相关文章推荐

构建,重构二叉树并输出

  • 2010年11月06日 20:12
  • 870KB
  • 下载

真二叉树重构

  • 2016年01月19日 14:36
  • 2KB
  • 下载

数据结构与算法学习笔记——二叉树重构(递归)

关于二叉树的另外一个重要内容就二叉树的重构,二叉树的重构就是根据已知的二叉树前序,中序,后续遍历的数组重新构造出园二叉树。 对于普通的二叉树可以由 前序遍历+中序遍历 或者 后序遍历+中序遍历 重构...

C语言打印二叉树 重构版

  • 2014年03月26日 14:26
  • 4KB
  • 下载

根据中序遍历结果和前序(后序)遍历结果重构二叉树

问题描述:输入某二叉树的中序和前序(后序)遍历结果,请重构出该二叉树。 首先,我们需要回顾二叉树的三种遍历方式: 前序遍历:根+左子树+右子树 中序遍历:左子树+根+右子树 后序遍历:左子树+右子树+...

Tsinghua OJ:真二叉树重构(Proper Rebuild)

真二叉树重构(Proper Rebuild) Description In general, given the preorder traversal sequence and postor...

THU数据结构编程作业一:真二叉树重构(Proper Rebuild)

本题是对二叉树进行重构,与普通的二叉树重构不同的是本题是针对特殊的二叉树——真二叉树进行重构。 对于普通的二叉树我们知道可以通过 中序遍历+ 前序遍历/后序遍历 完成重构,并且如果仅已知前序遍历和后...

剑指offer之重构二叉树

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

剑指offer面试题6 前序遍历&中序遍历,后序遍历&中序遍历重构二叉树

重构二叉树目前主要是采取递归的方式 目前只能通过前序,中序 或者 后续,中序进行重构 前序和后序是不能够重构的,举个例子:  前序: 1 2 4 7 3 5 6 8  后续: 7 4 2 5 8 6 ...

重构二叉树,java实现,剑指offer原题

题目描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:重构二叉树
举报原因:
原因补充:

(最多只允许输入30个字)