剑指offer-06:重建BinaryTree

来源:互联网 发布:c语言和指针 编辑:程序博客网 时间:2024/06/10 09:54

输入二叉树的前序遍历和中序遍历的结果,重建出二叉树。假设输入序列不含重复数字。

根据前序遍历和中序遍历结果,可以构建出唯一的二叉树。这是一个基本功。

前序序列={根节点,左子树,右子树}
中序序列={左子树,根节点,右子树}

二叉树的定义:

struct BinaryTreeNode{    int value;    BinaryTreeNode * pLeft;    BinaryTreeNode * pRight;};
// 构建二叉树BinaryTreeNode * Construct(int *preorder, int * inorder, int length){    if(preorder == nullptr || inorder == nullptr || length <= 0)        return nullptr;    return ConstructCore(preorder, preorder+length-1, inorder, inorder+length-1);}BinaryTreeNode * ConstructCore(int * startPreorder, int *endPreorder, int *startInorder, int *endInorder){    // the first value in preorder is the root node    int rootValue = startPreorder[0];    BinaryTreeNode * root = new BinaryTreeNode();    root->value = rootValue;    root->pLeft = root->pRight = nullptr;    // only one node    // 因为最终都会分解到单结点,所以从此处可判断序列是否一一相等    if(startPreorder == endPreorder)    {        // the same root node value        if(startInorder == endInorder && *startPreorder == *startInorder)            return root;        else             throw std::exception("Invalid input");    }    // 左子树和右子树的分解    int * rootInorder = startInorder;    while(rootInorder <= endInorder && *rootInorder != rootValue)        ++rootInorder;    // no the value    if(rootInorder==endInorder && *rootInorder != rootValue)        throw exception("Invalid input");    // find the position of the root node    int leftLength = rootInorder - startInorder;    int * leftPreorderEnd = startPreorder + leftLength;    // left sub_tree exists    if(leftLength > 0)    {        root->pLeft = \        ConstructCore(startPreorder+1, leftPreorderEnd, startInorder, rootInorder-1);    }    // right sub_tree exists    if(leftLength < (endPreorder-startPreorder))    {        root->pRight = \        ConstructCore(leftPreorderEnd+1, endPreorder, rootInorder+1, endInorder);    }    return root;}
// 递归方式:先序输出二叉树void printPreorder( BinaryTreeNode * t){    if(t != nullptr)    {        cout << t->value << " ";        printPreorder(t->pLeft);        printPreorder(t->pRight);    }    else        return;}

递归和迭代2种思想,3种遍历,共6种算法,参见此处博文


// 测试int main(int argc, _TCHAR* argv[]){    int a[]={1,2,4,7,3,5,6,8};    int b[]={4,7,2,1,5,3,8,6};    BinaryTreeNode * root = Construct(a, b, 8);    printPreorder(root);    return 0;}