【问题标题】:Converting a preorder traversal array to an level order traversal array (or vice versa) given that the binary tree was filled in Level Order假设二叉树是按级别顺序填充的,将前序遍历数组转换为级别顺序遍历数组(反之亦然)
【发布时间】:2017-11-01 04:26:32
【问题描述】:

假设您有一个按级别顺序填充的二叉树,即每个级别都在该级别的任何节点的子节点之前填充。这样的树可以通过它的级别顺序遍历来唯一定义。例如 {1,2,3,4,5,6} 是

    1
 2     3
4 5   6

对此的前序遍历将产生数组 {1,2,4,5,3,6}

有没有办法将这些数组中的一个直接转换为另一个,这比生成实际的树并在其上执行实际遍历更快? (对于有 n 个节点的树)

【问题讨论】:

    标签: tree binary-tree tree-traversal preorder


    【解决方案1】:

    是的,这两者都可以在一次通过中实现。

    首先,预购级别,因为这更容易一些。由于这是一个水平填充树,对于数组中的任何节点,给定它的索引i,左子树节点的索引公式为2*i+1,右为2*i+2。因此,我们以预先顺序递归调用它们,将根节点附加到所需数组的后面。

    def level_to_pre(arr,ind,new_arr):
        if ind>=len(arr): return new_arr #nodes at ind don't exist
        new_arr.append(arr[ind]) #append to back of the array
        new_arr = level_to_pre(arr,ind*2+1,new_arr) #recursive call to left
        new_arr = level_to_pre(arr,ind*2+2,new_arr) #recursive call to right
        return new_arr
    

    然后这样调用,这里将填充最后一个空白数组。

    ans  = level_to_pre([1,2,3,4,5,6],0,[])
    

    现在在我进入 pre to level 部分之前,请记住 dfs 使用递归,它在后台使用堆栈。 bfs 使用队列的地方。而我们手中的问题,以层优先顺序填充数组,基本上是 bfs。因此,我们将不得不显式维护一个队列来模拟这些递归调用,而不是递归调用(即堆栈)。

    我们在这里所做的是,给定子树的根,我们首先将它添加到答案数组。现在,与上面的问题不同,查找子节点的索引具有挑战性。左边的很简单,root之后就可以了。为了找到右索引,我们计算左子树的总大小。这是可能的,因为我们知道它是水平填充的。我们现在使用一个辅助函数left_tree_size(n),它返回给定整个树的大小的左子树的大小。因此,除了根的索引之外,在递归的情况下我们将传递的第二个参数是这个子树的大小。为了反映这一点,我们在队列中放置了一个 (root,size) 元组。

    from math import log2
    import queue
    
    def pre_to_level(arr):
        que = queue.Queue()
        que.put((0,len(arr)))
        ans = [] #this will be answer
        while not que.empty():
            iroot,size = que.get() #index of root and size of subtree
            if iroot>=len(arr) or size==0: continue ##nodes at iroot don't exist
            else : ans.append(arr[iroot]) #append to back of output array
            sz_of_left = left_tree_size(size) 
            que.put((iroot+1,sz_of_left)) #insert left sub-tree info to que
            que.put((iroot+1+sz_of_left,size-sz_of_left-1)) #right sub-tree info 
    
        return ans
    

    最后,这里是辅助函数,通过几个例子来弄清楚它为什么起作用。

    def left_tree_size(n):
        if n<=1: return 0
        l = int(log2(n+1)) #l = no of completely filled levels
        ans = 2**(l-1)
        last_level_nodes = min(n-2**l+1,ans)
        return ans + last_level_nodes -1
    

    【讨论】:

      猜你喜欢
      • 2017-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多