我试图插入" KONTINUASJONSEKSAMEN"到空堆上。结果应该产生" USTSOSNOMNJNNEKAAKEI",这是我无法做到的。我最终选择了" UTSSOONSMNJNNEKAAKEI"我从可视化下工作。
U
/ \
T S
/ \ / \
S O O N
/ \ / \ / \ / \
S M N J N N E K
/ \ /\ /
A A K E I
我从顶部的第一个K开始,向下,从左到右与剩余的单词一起转换,使用价值较高的孩子转换价值较低的父母。更高的值意味着更接近Z.
你知道我哪里出错吗?答案 0 :(得分:2)
我认为问题在于你自上而下插入,而堆是通过自下而上插入来构建的。我使用自己的堆实现来进行自下而上的插入,并且从该输入字符串产生的堆正是您预期的输出。
如果你在二进制堆中进行自上而下的插入,那么在遇到这种情况时会有歧义:
K
S S
A B C D
也就是说,您插入的节点小于其子节点,并且两个子节点相等。
哪个' S'你选择交换吗?如果你总是选择左边的那个,而其他人总是选择右边的那个,那么得到的堆可能会大不相同。例如:
S S
K S S K
A B C D A B C D
两者都是有效的堆。
通常,堆插入是通过将新节点添加为堆的最后一个节点,然后将其向上冒泡到树的正确位置来完成的。所以,如果你从根开始使用K并添加O,那么你有:
K
O
你注意到O大于K,所以你交换节点给你:
O
K
然后你添加N并获得
O
K N
首先将T添加为堆的最后一个节点,并将其冒泡:
O
K N
T
T大于K,因此您交换节点:
O
T N
K
T大于O,所以你交换它们:
T
O N
K
以这种方式自下而上插入,没有歧义。
您还应注意,自下而上插入比自上而下插入更有效。如果在顶部插入,则总是采用log 2 (n)次迭代,其中n是当前堆中的项目数。即使新项目替换了根目录,您也必须对其进行筛选,直到您在叶级别有新条目为止。
当您通过首先将新节点放在叶级别进行自下而上插入时,节点将保持在叶级别的一半时间。节点赢得超过一个级别的时间有75%。只有当新项目替换根时,才需要执行log 2 (n)交换。有一个很好的论据可以说二进制堆插入是O(1),但是假定自下而上插入。有关详细信息,请参阅Argument for O(1) average-case complexity of heap insertion。
有关如何实施自下而上插入的详细信息,请参阅http://blog.mischel.com/2013/09/29/a-better-way-to-do-it-the-heap/上关于堆的博客系列。
答案 1 :(得分:0)