重建二叉树

二叉树最为另一种重要的数据结构,当然需要好好的掌握。

二叉树的重建方法思想一般是找到二叉数的根节点,确定左子树,确定右子树,然后递归。

这里是第一种题形:

输入二叉树的前序遍历和中序遍历结果,重建二叉树。假如前序遍历序列为{1,2,4,7,3,5,6,8},中序遍历序列为{4,7,2,1,5,3,8,6}

第一确认根节点:由前序遍历可知根节点为1,即前序遍历的第一个数。

第二确认左右子树:由中序遍历可知在中序遍历的根节点之前的为左子树,之后的为右子树。所以左子树为{4,7,2},右子树为{5,3,8,6}

第三递归重建,如左子树的前序遍历为{2,4,7}右子树的中序遍历为{4,7,2}根据上面方法确定左子树根节点。。。。

下面是代码:

struct BinaryTreeNode
{
    int value;
    BinaryTreeNode* p_left;
    BinaryTreeNode* p_right;
};

BinaryTreeNode* ConstructCore( int* startPreorder, int* endPreorder, int* startInorder, int* endInorder)
{
    //确定创建根节点
    int rootValue = startPreorder[0];
    BinaryTreeNode* root = new BinaryTreeNode();
    root->value = rootValue;
    root->p_left = root->p_right = NULL;

    if(startPreorder == endPreorder)
    {
        if(startInorder == endInorder && *startPreorder == *startInorder)
            return root;
        else
        {
            cout<<"非法输入"<<endl;
            throw std::exception("Invalid input");
        }
    }

    //寻找中序遍历中根节点的位置
    int* rootInorder = startPreorder;
    while(rootInorder <=endInorder && *rootInorder !=rootValue)
        ++rootInorder;
    //如果在中序遍历中没找到相应根节点
    if(rootInorder == endInorder && *rootInorder != rootValue)
    {
        cout<<"非法输入,创建失败"<<endl;
        return NULL;
    }

    //确认左子树
    int leftlength = rootInorder - startInorder;
    int *leftPreorderEnd = startPreorder+leftlength;
    if(leftlength > 0 )
    {
        //递归重建左子树
        root->p_left = ConstructCore(startPreorder+1,leftPreorderEnd,startInorder,rootInorder-1);
    }

    if(leftlength < endInorder - startInorder)
    {
        //递归重建右子树
        root->p_right = ConstructCore(leftPreorderEnd+1,endPreorder,rootInorder+1,endInorder);
    }
    return root;
}

BinaryTreeNode*  Construct(int* preorder, int* inorder, int length)
{
    if( preorder == NULL || inorder == NULL || length <=0 )
            return NULL;

    return ConstructCore(preorder,preorder+length-1,inorder,inorder+length-1);
}

 

posted @ 2013-03-02 14:56  没离开过  阅读(128)  评论(0)    收藏  举报