重建二叉树

来源:互联网 发布:阳炎ene软件 编辑:程序博客网 时间:2024/06/06 04:20

关于二叉树的重建,我总结如下,并以图文的形式展示:

一颗二叉树,已知先序遍历和中序遍历,要求还原出二叉树,问题不难,关键是细节:

思想:

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

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

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

以上过程,递归就显得很重要:

先上一张图:


假设这是需要我们重新构建的二叉树。

此二叉树的前序遍历为:1,2,4,7,3,5,6,8

                   中序遍历为:4,7,2,1,5,3,8,6

再看:


同样的方法在子树中递归重建子树,以下是代码:

//声明重构BinaryTreeNode* ConstructCore(int* startPreorder, int* endPreorder, int* startInorder, int* endInorder);//重构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);}BinaryTreeNode* ConstructCore(    int* startPreorder, int* endPreorder,     int* startInorder, int* endInorder){    //前序遍历序列的第一个数字是根结点的值    int rootValue = startPreorder[0];//重构第一个根节点    BinaryTreeNode* root = new BinaryTreeNode();    root->m_nValue = rootValue;    root->m_pLeft = root->m_pRight = NULL;//前序的头和尾相等的时候    if(startPreorder == endPreorder)    {//并且中序头和尾也相等,前序头和中序头相等,只说明只有一个节点if (startInorder == endInorder && *startPreorder == *startInorder){            return root;}    }    // 在中序遍历中找到根结点的值    int* rootInorder = startInorder;while (rootInorder <= endInorder && *rootInorder != rootValue){        ++ rootInorder;}if (rootInorder == endInorder && *rootInorder != rootValue){cout << "非法序列" << endl;return;}//while循环结束,跳过,意思是找到了根节点//求出左子树的长度leftLength    int leftLength = rootInorder - startInorder;  //虽然是指针相减,但指针内部也是整数    int* leftPreorderEnd = startPreorder + leftLength; //找到前序遍历左子树最后一个节点    if(leftLength > 0)    {        // 构建左子树//startPreorder + 1 原来前序的头往前走一个        root->m_pLeft = ConstructCore(startPreorder + 1, leftPreorderEnd,             startInorder, rootInorder - 1);    }    if(leftLength < endPreorder - startPreorder)    {        // 构建右子树        root->m_pRight = ConstructCore(leftPreorderEnd + 1, endPreorder,            rootInorder + 1, endInorder);    }    return root;}
赐教!




1 0