二叉树的创建

二叉树的创建

以前文章里面提到过二叉树的遍历分三种方式,前序遍历,中序遍历和后序遍历,那么二叉树的构建过程也可以分这三种顺序,最常用的应该是先序创建二叉树,比较符合我们的直观想法。
我在实际中遇到的二叉树的创建问题较少,更多的是给定一个二叉树然后对二叉树进行操作。最近遇到了几个题目,跟二叉树的创建有关,也是考验算法的题目,现在记录一下。


根据中序和后序遍历顺序构建二叉树

这个题目一开始想,既然中序和后序已经给出了,那么二叉树就已经创建好了应该?那就何必再构建一次。不过仔细一想,这是考验我基本算法和代码的能力。
思路如下:

  • 先找到后序遍历的最后一个节点D,该节点就是头结点
  • 从中序遍历的第一个节点开始迭代,直到找到头结点D,该节点的左边就是左子树,右边就是右子树,并记录下从第一个节点到D节点的长度L。
  • 后序遍历的前面一段长度为L的就是左子树,剩下的去掉最后一个节点就是右子树。
  • 递归的计算下去,直到所有的节点都处理完毕
    借鉴了网上的代码,如下:
TreeNode *createTree(vector<int> &inorder, int inBeg, int inEnd, vector<int> &postorder, int postBeg, int postEnd)
    {
        if (inBeg > inEnd)
            return NULL;

        int root = postorder[postEnd];

        int index;

        for(int i = inBeg; i <= inEnd; i++)
            if (inorder[i] == root)
            {
                index = i;
                break;//找到头结点
            }

        int len = index - inBeg;//计算左子树的节点数目
        TreeNode *left = createTree(inorder, inBeg, index - 1, postorder, postBeg, postBeg + len - 1);
        TreeNode *right = createTree(inorder, index + 1, inEnd, postorder, postBeg + len, postEnd - 1);

        TreeNode *node = new TreeNode(root);
        node->left = left;
        node->right = right;

        return node;
    }

    TreeNode *buildTree(vector<int> &inorder, vector<int> &postorder) {
        if (inorder.size() == 0)
            return NULL;

        TreeNode *head = createTree(inorder, 0, inorder.size() - 1, postorder, 0, postorder.size() - 1);

        return head;
    }

根据中序和先序遍历顺序构建二叉树

这个思路是类似的
首先是找到先序遍历的第一个节点,即为root结点,之后在中序遍历中找到头结点D,该节点的左边就是左子树,右边就是右子树,用跟上述类似的递归方法实现。
代码如下:

TreeNode *buildTree(vector<int> &preorder, vector<int> &inorder) {
    return create(preorder, inorder, 0, preorder.size() - 1, 0, inorder.size() - 1);
}

TreeNode* create(vector<int>& preorder, vector<int>& inorder, int ps, int pe, int is, int ie){
    if(ps > pe){
        return nullptr;
    }
    TreeNode* node = new TreeNode(preorder[ps]);
    int pos;
    for(int i = is; i <= ie; i++){
        if(inorder[i] == node->val){
            pos = i;
            break;
        }
    }
    node->left = create(preorder, inorder, ps + 1, ps + pos - is, is, pos - 1);
    node->right = create(preorder, inorder, pe - ie + pos + 1, pe, pos + 1, ie);
    return node;
}

当然也有非递归的实现方法,实现起来稍显麻烦,后续会进行总结。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值