Swift通过前序遍历和中序遍历实现重构二叉树

剑指Offer题目如下:
输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树。假设输入的前序遍历和中序遍历的结果中都不含重复的数字。例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建二叉树并返回。

前序遍历 遍历顺序是:A->B->C
在这里插入图片描述
中序遍历 遍历顺序是 :B->A->C

前序代码:

traverse(node : TreeNode)
{if node == null{
return null
}
访问该节点 按照该例子就是把node.val加进前序数组
traverse(node.left)
traverse(node.right)
}
}

中序代码:

traverse(node : TreeNode)
{if node == null{
return null
}

traverse(node.left)
访问该节点 按照该例子就是把node.val加进中序数组
traverse(node.right)
}
}

综上可以知道,如果给出的是前序遍历数组,他会先遍历每个小二叉树顶点,一直到最左边,所以用来分割成左右子树需要用前序遍历的每个节点;如果给出的是中序遍历数组,你可以利用前序遍历中得到的节点,找到他在中序遍历的位置,就可以把中序遍历数组分成左右两个子树数组了。我们使用递归方法,一步步把数组才分成左右子树分到不同的树节点。

下面是swift实现代码

import Foundation

public class TreeNode {
    public var left : TreeNode?
    public var right : TreeNode?
    public var val : Int = 0
    public func initWithValue(_ value : Int) {
        self.val = value
        self.left = nil
        self.right = nil
    }
}

class Solution {
    func RecreateBinaryTree(by pre : [Int] , by mid : [Int] ) -> TreeNode? {
        
        return buildTree(pre: pre, preStart: 0 , preEnd: pre.count - 1 , mid: mid, inStart: 0, inEnd: mid.count - 1)
        
    }
    
    func buildTree(pre : [Int] , preStart : Int, preEnd : Int  , mid : [Int] , inStart : Int , inEnd : Int) -> TreeNode? {
        
        if preStart > preEnd {
            return nil
        }
        
        let value = pre[preStart]
        
        let node = TreeNode()
        
        node.initWithValue(value)
        
        var index = inStart
        
        while mid[index] != value {
            index += 1
        }
        
        node.left = buildTree(pre: pre, preStart: preStart + 1, preEnd:preStart + inStart - index, mid: mid, inStart: inStart, inEnd: index-1)
        
        node.right =  buildTree(pre: pre, preStart:preStart + inStart - index + 1 , preEnd: preEnd, mid: mid, inStart: index + 1, inEnd: inEnd)
        
        return node
        
    }
}

来看看这句
node.left = buildTree(pre: pre, preStart: preStart + 1, preEnd:preStart + inStart - index, mid: mid, inStart: inStart, inEnd: index-1)
这个函数里面的参数首先由pre的数组以及其开始位置和结束位置和mid的数组以及其开始位置和结束位置构成 。pre数组就是用来提供根节点的,所以preStart+1传进去就行,但是知道根节点后,我们怎么知道pre数组几位到几位是给left的呢,这时候就要看mid数组了,我们需要用index去找到终点嘛,这个index偏移了多少位才找到中间节点,而这个多少位就是用来说明有多少个属于左子树的,我们就可以使用inStart - index来得出左子树的个数,再加上preStart就可以知道哪段范围在pre数组是属于左子树的。
node.right就跟上面思路一样。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值