我正在复习算法理论(来自Cormen)。章节中有一个关于二叉树的练习题,问:
“最小堆属性是否可以用于在O(n)时间内按排序顺序打印n个节点树的键?说明如何做到,或者为什么不行。”
我认为是可以的。在最小堆中,节点中的元素比其两个子节点都要小。因此,堆的根始终是所有n个元素中较小的元素,而根的左子节点比左子树中的所有元素都小,右子节点比右子树中的所有元素都小,以此类推。
因此,如果我们不断提取根、打印它,然后使用其子节点中较小的一个更新根,就可以保持最小堆属性并按排序顺序打印。 (我想的是不基于数组的最小堆)。
因此,这可以在O(n)时间内完成,因为要更新根,我们只需比较2个子节点并将根的指针更新为其中较小的一个。
但是我在这里检查了解决方案: Cormen Supplement Solutions 它谈到了最大堆,并且说不能在O(n)时间内完成:
在堆中,节点的键是其两个子节点的键。在二叉搜索树中,节点的键是其左子节点的键,但是右子节点的键。堆属性不像二叉搜索树属性那样有助于按排序顺序打印节点,因为它不能告诉我们节点之前包含要打印的元素的哪个子树。在堆中,小于该节点的最大元素可能在任一子树中。请注意,如果堆属性可以用于在O(n)时间内按排序顺序打印键,则我们将拥有一个O(n)时间算法来进行排序,因为构建堆仅需要O(n)时间。但是我们知道(第8章)比较排序必须花费(n lg n)时间。
从我的角度来看,我可以理解使用最大堆无法在O(n)时间内打印它们。但是,使用我解释的最小堆属性是否可能做到呢?此外,为什么解决方案忽略了最小堆。这是笔误还是错误?
我是否有什么误解?
“最小堆属性是否可以用于在O(n)时间内按排序顺序打印n个节点树的键?说明如何做到,或者为什么不行。”
我认为是可以的。在最小堆中,节点中的元素比其两个子节点都要小。因此,堆的根始终是所有n个元素中较小的元素,而根的左子节点比左子树中的所有元素都小,右子节点比右子树中的所有元素都小,以此类推。
因此,如果我们不断提取根、打印它,然后使用其子节点中较小的一个更新根,就可以保持最小堆属性并按排序顺序打印。 (我想的是不基于数组的最小堆)。
因此,这可以在O(n)时间内完成,因为要更新根,我们只需比较2个子节点并将根的指针更新为其中较小的一个。
但是我在这里检查了解决方案: Cormen Supplement Solutions 它谈到了最大堆,并且说不能在O(n)时间内完成:
在堆中,节点的键是其两个子节点的键。在二叉搜索树中,节点的键是其左子节点的键,但是右子节点的键。堆属性不像二叉搜索树属性那样有助于按排序顺序打印节点,因为它不能告诉我们节点之前包含要打印的元素的哪个子树。在堆中,小于该节点的最大元素可能在任一子树中。请注意,如果堆属性可以用于在O(n)时间内按排序顺序打印键,则我们将拥有一个O(n)时间算法来进行排序,因为构建堆仅需要O(n)时间。但是我们知道(第8章)比较排序必须花费(n lg n)时间。
从我的角度来看,我可以理解使用最大堆无法在O(n)时间内打印它们。但是,使用我解释的最小堆属性是否可能做到呢?此外,为什么解决方案忽略了最小堆。这是笔误还是错误?
我是否有什么误解?