当前位置: 首页 > 知识库问答 >
问题:

将前序遍历数组转换为级别顺序遍历数组(反之亦然),因为二叉树以级别顺序填充

袁运良
2023-03-14

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

    1
 2     3
4 5   6

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

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

共有1个答案

翟曦之
2023-03-14

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

首先,升级到预订,因为这更容易一些。由于这是一个级别填充的树,对于数组中的任何节点,给定它的索引 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使用递归,它在场景后面使用堆栈。而bfs使用队列。我们手中的问题,按级别优先顺序填充数组,基本上是bfs。因此,我们将不得不显式维护一个队列来模拟这些递归调用,而不是递归调用(即堆栈)。

我们在这里做的是,给定子树的根,我们首先将其添加到答案数组中。现在,寻找子节点的索引很有挑战性,不像上面的问题。左一个很容易,它会紧跟在根之后。为了找到右的索引,我们计算左子树的总大小。这是可能的,因为我们知道它已经填满了级别。我们现在使用一个帮助函数left_tree_size(n),它在给定整棵树的大小的情况下返回左子树的大小。所以,除了root的索引之外,我们在递归情况下要传递的第二个参数是这个子树的大小。为了反映这一点,我们在队列中放置一个(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

最后,这里是helper函数,下面是一些示例,以了解其工作html" target="_blank">原理。

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
 类似资料:
  • 我正在尝试编写一个函数,该函数将使用级别顺序遍历将一个元素插入到二叉树中。我的代码遇到的问题是,当我在树中插入一个新节点后打印级别顺序遍历时,它以无限循环的方式打印元素。1,2,3,4,5,6,7,8这个数字一直在飞驰过终点站。我将感谢任何关于如何补救这种情况的指示和建议。 这是我通过修改级别顺序遍历技术将一个元素插入到树中的地方 主

  • 我正在尝试对二叉树进行级别顺序遍历。但诀窍是代替正常的级别顺序遍历,我想做另一种选择。对于例如。 普通等级顺序遍历 : 我要找的是我们打印根。现在,对于每一个偶数级,我都想逆时针旋转,对于每奇数级,都会顺时针旋转: 对于这种遍历,输出应该是: 这是我到目前为止尝试的,但这产生的输出与我试图实现的输出略有不同: 该程序产生以下输出: < code>1 3 2 5 4 7 6 10 11 9 8 我需

  • 我想在级别顺序遍历中打印出BST。但是我以这种奇怪的方式得到了输出。此外,我使用Java可视化工具来检查我的算法,没有线索,因为可视化工具没有说明多个实例。我在想,要么我的变量没有正确地添加到我的实例中,要么没有添加到

  • 这是一个leetcode问题。 给定一个二叉树,返回其节点值的级序遍历(即从左到右,逐级)。 例如:给定二叉树, 将其级别顺序遍历返回为: 但我正在用JavaScript尝试一种新的方式,而不是完全按照他们的解决方案。到目前为止,我能够打印阵列,但 如何在新行中打印不同的级别 以下是我目前的代码: 输入:[3,9,20,空,空,15,7], LeetCode问题链接:BinarytreeTrave

  • 我想逐级显示树结构。我当前的代码执行BFS或级别顺序遍历,但我无法使输出像树一样显示树结构。请参阅当前输出和预期输出。 我的想法是使用某种计数来迭代队列中同一级别的元素。 我怎么能这样做呢。 没有此功能的原始代码可以在下面的链接中找到,以防有人需要整个实现,否则只需查看下面的显示BFS功能。 java中泛型树(n元树)的级顺序遍历 谢谢 另外,我之前发布了一个具有相同功能的逻辑问题,因为已经回答了

  • 我想对二叉树执行级别顺序遍历。因此,对于给定的树,说: 产出将是: 我知道我可以使用某种队列,但在C中递归地实现这一点的算法是什么?感谢您的帮助。