我试图理解为什么这个问题的答案是C.根据我刚看到的一个讲座,PriorityQueue保持最小的元素在前面,其余的没有关系或没有设置订购。因此,当添加小于当前最小值的值时,当前min将移动到队列的末尾或列表的后面,并且新的min将位于前面。这个逻辑似乎不适用于此,所以我想我错过了一些东西。在视频中提到索引0不会被使用,但我找不到原因。我想知道这是否是我所遗漏的。剩下的价值观是怎么回事?
这就是发生的事情。
46个
26 46
18 46 26
15 18 26 46
9 15 26 46 18
9 15 26 46 18 38
9 15 12 46 18 38 26
9 15 12 45 18 38 26 46
这是我使用上面解释的逻辑的原因
46个
26 46
18 46 26
15 46 26 18
9 46 26 18 15
9 46 26 18 15 38
9 46 26 18 15 38 12
9 46 26 18 15 38 12 45
答案 0 :(得分:1)
优先级队列组织元素(如果它是最小队列),以便根是最小元素。
请注意,在此示例中,队列由堆数据结构支持,堆存储为数组。堆保持根大于其子节点(左和右)的属性,并且每个子节点共享相同的属性,因为每个子节点都大于其子节点。堆的这个属性是回答您发布的问题的关键。
https://www.cs.auckland.ac.nz/~jmor159/PLDS210/heaps.html
上面的文字有一个插入堆的原理图,可以回答你的问题。在示例中,元素一个接一个地插入,并且它们向上传播(在某些实现中称为siftup)到堆数据结构中的位置,并且添加n个元素需要nlogn复杂度。
我建议通过重复插入元素将堆绘制为二叉树,你也会得到相同的结论,即(c)。
如果您对尝试使用某些Java代码感兴趣,可以下载两个类来实现堆的基本实现并使用它们。他们在:
http://khanna111.com/wordPressBlog/2013/06/
请注意,此实现使用“siftDown”方法,其中将给定的“n”元素数组转换为o(n)复杂度的堆。您可以下载代码并使用它并自己实现“siftUp”方法以获得对堆数据结构的理解。请注意,代码是Java。
答案 1 :(得分:1)
不使用第零个元素,因为优先级队列是使用数组堆实现的。
数组堆具有位置i
'元素的两个子元素位于(i * 2)
和(i * 2) + 1
的属性。此外,位置i
的父节点因此位于数组中的(i / 2)
位置。
如果根节点的位置为0,则无法进行此操作;在这种情况下,乘法不起作用。排除第一个位置0
将允许使用上述两个属性创建树结构。这将允许使用常量时间数组操作快速操作堆。
当从堆中删除项目(换句话说,位置1
中的项目从数组中删除)时,它将替换为数组堆中的最后一项。然后,这个值“向下冒泡”,与其较小的子进行交换,直到满足最小堆条件(节点的子节点都比自身大)。
答案 2 :(得分:0)
PriorityQueue
是基于min-heap
的抽象数据结构。所以堆上的元素之间肯定有一个顺序,即具有最小值的对象将更接近根。但是min-heap
的目标是找到min元素而不是对元素进行排序。因此,如果你遍历元素,你会发现它们没有特定的顺序放在堆上。