在互联网上看到这个问题并试图解决它。我可以解决堆是严格二叉树的情况(通过重复分区前序遍历),但当堆只是一棵完整的二叉树时,我无法找出算法。
例如,如果 1, 2, 3, 4, 5, 6, 7
是最小堆的预序遍历,
堆的大小为7
1
是堆中的第一个元素(考虑到堆表示为数组)
下一个(大小-1)/2
元素将位于1
的左子树中
2、3、4
将位于 1
的左侧子树中
最后一个(大小 - 1)/ 2
个元素将位于 1
的右子树中
5、6、7
将位于 1
的右侧子树中
可以通过递归地应用这个逻辑来构造完整的堆。
该解决方案将适用于此类堆是严格二叉树的情况
1
2 3
4 5 6 7
但显然,这在非叶元素有一个子元素或没有子元素的堆的情况下不起作用。例如,
1 1
2 3 2 3
4 5 6 4 5
我想不出任何干净的算法可以做到这一点。任何解决方案/建议都会很有帮助。
将前序遍历转换为标准堆表示应该很简单。预订单访问自己,左,右。对于基于1的数组中的堆,节点N的左子节点位于2N,右子节点位于2N-1。这直接导致了这个算法:
def constructHeap(preorder, pidx, heap, hidx)
return pidx if (hidx>=heap.size) #no more children
heap[hidx] = preorder[pidx] #self
pidx = constructHeap(preorder, pidx+1, heap, hidx*2) #left
return constructHeap(preorder, pidx, heap, hidx*2+1) #right
end
preorder = [1,2,3,4,5,6,7]
heap = Array.new(preorder.size+1) #create storage
constructHeap(preorder, 0, heap, 1)
puts heap
你试图通过应用给你的两条信息中的一条来解决这个问题。
你掌握的信息是:
现在,虽然您通常需要两次二进制遍历才能获得第三次遍历(前、后,依次为三次),但这里有一个额外的信息:二进制树是一个堆。
二叉堆总是一棵完整的二叉树。完整的二叉树是这样一棵二叉树,树的所有级别都满了,也许除了最后一个级别,它总是从左到右填充。换句话说,堆不可能有一个小于两个子节点的内部节点。
看几个例子会让这变得更容易。随着孩子数量的增加,我们看到以下模式:
继续这样,当孩子的数量在2到6之间时,我们会得到以下分割:
(1, 1), (2, 1), (3, 1), (3, 2), (3, 3)
当孩子的数量在6到14之间时,我们得到:
(3, 3), (4, 3), (5, 3), (6, 3), (7, 3), (7,4), (7, 5), (7, 6), (7, 7)
所以当孩子的数量在(2^k-2)和(2^{k 1}-2)之间时,我们得到:
either a split of the form (2^{k-1}-1+l, 2^{k-1}-1) where 0 <= l <= 2^{k-1} or
(2^k-1, 2^{k-1}-1+l) where 0 <= l <= 2^{k-1}
逻辑是找到一个k,这样(2^k-2)
Let l = childCount - (2^k-2)
If l <= 2^{k-1}
split with (2^{k-1}-1+l, remaining)
Else
split with (2^k-1, remaining)
我知道有一些方法可以从预序遍历(作为数组)构造树。更常见的问题是构造它,给定顺序和顺序遍历。在这种情况下,虽然inorder遍历是多余的,但它肯定会使事情变得更容易。有谁能给我一个关于后命令遍历的想法吗?迭代和递归都是需要的。 我试着用堆栈迭代地做,但根本无法得到正确的逻辑,所以得到了一个可怕的乱七八糟的树。递归也是如此。
我已经实现了一种方法来对一棵树(不是二叉树)进行预排序遍历。此树的每个父节点都有一个子节点数组,因此我使用的方法是: 将子节点链接到父节点“tnAA”的示例 但它只输出根节点,这种方法有什么问题? 解决方案:将children数组链接到每个parent:tnaa . setchildern(AA _ childern);
我仍然是Java的初学者。我刚刚学习了二分搜索法树和前序遍历的概念,以及如何使用递归来实现二叉树的前序遍历。大概是这样的: 但是,如何为 N 元树实现相同的递归模型呢?其中每个节点的子节点数不一定为 2?因为.left和.right将不适用,不是吗?如果需要提供更多代码,请lmk,谢谢。
下面是将二叉查找树的前序遍历转换为原始树的代码。 下面的代码采用整数数组,表示二进制搜索树的预序遍历。返回构造树的根。 来源:http://www . geeks forgeeks . org/construct-BST-from-given-preorder-traversal-set-2/ 我无法理解此代码。有人能帮我理解以下内容吗 > 在任何给定的迭代中,堆栈中存储的值与指出的当前值相关 从
我需要执行一个三元树的预购遍历。我很熟悉二叉树上的这种遍历,比如: 它按根、左、右顺序遍历。我很困惑如何在添加了中间子节点的情况下做到这一点。如果有人能解释这个,那就太好了。谢谢
本文向大家介绍用C ++中的给定操作构造最大堆栈的程序,包括了用C ++中的给定操作构造最大堆栈的程序的使用技巧和注意事项,需要的朋友参考一下 假设我们要制作一个最大的堆栈,它支持以下操作- MaxStk() 这将构造一个最大堆栈的新实例 push(val) 将val插入堆栈 top() 从堆栈中获取最高的元素 max() 从堆栈中获取最大元素 pop() 从堆栈中删除并返回最上面的元素 popm