重建二叉树

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

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

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


主函数:

#include <iostream>
#include "function.h"

using namespace std;

/*重建二叉树*/
int main()
{
    int szPrevOrder[] = {1, 2, 4, 7, 3, 5, 6, 8};   //二叉树的先序遍历
    int szInOrder[] = {4, 7, 2, 1, 5, 3, 8, 6};     //二叉树的中序遍历
    int nodeNum = sizeof(szPrevOrder)/sizeof(int);
    BinaryTreeNode *root = BulidBinaryTree(szPrevOrder, szInOrder, nodeNum);
    cout<<"PrevOrder: ";
    PrevOrder(root);
    cout<<endl<<"InOrder:   ";
    InOrder(root);
    cout<<endl<<"PostOrder: ";
    PostOrder(root);
    cout<<endl;

    return 0;
}



  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值