Tree 如果二叉树是按级别顺序填充的,则将前序遍历数组转换为级别顺序遍历数组(反之亦然)

Tree 如果二叉树是按级别顺序填充的,则将前序遍历数组转换为级别顺序遍历数组(反之亦然),tree,binary-tree,tree-traversal,preorder,Tree,Binary Tree,Tree Traversal,Preorder,假设您有一个按级别顺序填充的二叉树,即每个级别在该级别的任何子节点之前填充。这样的树可以通过它的级别顺序遍历来唯一地定义。例如{1,2,3,4,5,6}是 1 2 3 4 5 6 对其进行预序遍历将生成数组{1,2,4,5,3,6} 有没有一种方法可以直接将这些数组中的一个转换为另一个,这比生成实际的树并在其上执行实际的遍历更快?(对于有n个节点的树)是的,这两个都可以在一次传递中实现 首先,升级到预订单,因为这更容易一点。由于这是一个级别填充树,对于数组中的任何节点,给

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

    1
 2     3
4 5   6
对其进行预序遍历将生成数组{1,2,4,5,3,6}


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

是的,这两个都可以在一次传递中实现

首先,升级到预订单,因为这更容易一点。由于这是一个级别填充树,对于数组中的任何节点,给定其索引
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,[])
现在,在我进入前到级别部分之前,请记住dfs使用递归,它在场景后面使用堆栈。其中,as bfs使用队列。我们手上的问题是,按一级顺序填充数组,基本上是bfs。因此,我们必须显式地维护一个队列来模拟这些递归调用,而不是递归调用(即堆栈)

我们在这里做的是,给定子树的根,我们首先将它添加到应答数组中。现在,查找子节点的索引是一项挑战,与上述问题不同。左一个很容易,它将在根之后立即出现。为了找到右索引,我们计算左子树的总大小。这是可能的,因为我们知道它的水平填充。我们现在使用一个helper函数
left\u tree\u size(n)
,它返回给定整棵树大小的左子树的大小。所以,除了根的索引,在递归的情况下,我们要传递的第二个参数是这个子树的大小。为了反映这一点,我们在队列中放入一个(根,大小)元组

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
最后,这里是helper函数,下面举几个例子来说明它为什么有效

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
def左树大小(n):
如果n