已知前序和中序构造原二叉树解析(C++)

首先简单给一段序列:

pre [] = {A, B, D, E, C, F}

in [] = {D, B, E, A, C, F }

原树:{A, B, C, D, E, NULL, F}

先序序列的首个结点一定为根节点,然后我们又从中序遍历知,其序列的根的左侧为左树,右侧为根的右树;

将树按先左后右依次创建,在左树中又可存在左子树;由前序序列性质知,根结点后为左侧结点,然后为右侧根节点,右侧子树,因此由前序和中序可以还原一棵原二叉树。

下面讲解一下代码实现原理,主要为递归创建,首先创建根节点引用传入,防止被复制,导致无法对一个根节点进行操作,传入存放前序和中序的数组,方便起见默认我们起始坐标为0,指明区间范围

判断区间是否符合要求,不符合将传入结点置空,此外判断是否存在左右子树,到时再做分析;

遍历创建左子树:

        mid:代表左侧根节点在中序序列中的下标,值代表以in[mid]为根结点的左侧结点数量

        intLeft:中序序列首下标不动

        preLeft = preLeft + 1 移动到根后一个单位,即左孩子(当preLeft > preRight时,即左侧节点创建完成是,终止,将当前节点置为null表示上一个调用该函数的左孩子为空)

        preRight:: preLeft + mid - inLeft:前序中左树的最后一个下标

        inRight = mid - 1 中序表中左树最后一位

        

        及传入左孩子之后的序列(第一次创建完根结点后传入per[1-3], 及根的左子树所有节点),然后开始构建根结点左侧的树,先左孩子后有孩子

        然后递归传入

mid:代表中序中根的下标,mid值表示以in[mid]为根左侧的结点数量
preLeft = preLeft + 1 移动到根后一个单位

 preLeft + mid - inLeft 前序中左树的最后一位下标

 inLeft:中序第一位,不动  

inRight = mid - 1 中序表中左树最后一位

template<typename T>
void CreateBinaryTreeHelp(BinTreeNode<T> *&r, T pre[], T in[], int preLeft, int preRight, int inLeft, int inRight) {
    if (preLeft > preRight || inLeft > inRight) {
        r = nullptr;
    } else {
        r = new BinTreeNode<T>(pre[preLeft]);
        int mid = inLeft;
        while (in[mid] != pre[preLeft]) {
            mid++;
        }
        //mid:代表中序中根的下标,mid值表示以in[mid]为根左侧的结点数量
        //preLeft = preLeft + 1 移动到根后一个单位  preLeft + mid - inLeft 前序中左树的最后一位下标  inLeft:中序第一位,不动  inRight = mid - 1 中序表中左树最后一位
        CreateBinaryTreeHelp(r->leftChild, pre, in, preLeft + 1, preLeft + mid - inLeft, inLeft, mid - 1);
        CreateBinaryTreeHelp(r->rightChild, pre, in, preLeft + mid - inLeft + 1, preRight, mid + 1, inRight);
    }
}

template<typename T>
BinaryTree<T> CreateBinaryTree(T pre[], T in[], int n) {
    BinTreeNode<T> *r;
    CreateBinaryTreeHelp<T>(r, pre, in, 0, n - 1, 0, n - 1);
    return BinaryTree<T>(r);
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值