重建二叉树

对于一颗二叉树,能够根据先序遍历(后序遍历)和中序遍历从新还原出二叉树。node

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

一、先序遍历序列的第一个元素一定是根节点,能够由此获取二叉树的根节点。函数

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

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

代码以下:code

#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;
}
相关文章
相关标签/搜索