- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
传统的Heapsort
算法在每次heapification
后将堆的最后一个元素与当前堆的根交换,然后再次继续该过程。但是,我注意到这是不必要的。
在子数组的堆化
之后,当节点包含最高值(如果它是max-heap
)时,数组中接下来的 2 个元素 < em>必须 跟在已排序数组的根之后,要么按照与现在相同的顺序,要么在反向排序时交换它们。因此,与其将根与最后一个元素交换,不如将前 3 个元素(包括节点以及在必要时交换第二个和第三个元素之后)与最后 3 个元素交换,这样 2随后的heapifications
(对于第二个和第三个元素)被免除了?
这种方法有什么缺点吗(除了如果需要交换第二个和第三个元素,这应该是微不足道的)?如果不是,如果确实更好,它会带来多少性能提升?这是伪代码:
function heapify(a,i) {
#assumes node i has two nodes, both heaps. However node i itself might not be a heap, i.e one of its children may be greater than its value.
#if so, find the greater of its two children, then swp the parent with that value.
#this might render that child as no longer a heap, so recurse
}
function create_heap(a) {
#all elements following index |_n/2_| are leaf nodes, thus heapify() should be applied to all elements within index 1 to |_n/2_|
}
function heapsort(a) {
create_heap(a); #a is now a max-heap
#root of the heap, that is a[1] is the maximum, so swap it with a[n].
#The root now contains an element smaller than its children, both of which are themselves heaps.
#so apply heapify(a,1). Note: heap length is now n-1, as a[n] is the largest element already found
#now again the array is a heap. The highest value is in a[1]. Swap it with a[n-1].
#continue
}
假设数组是[4,1,3,2,16,9,10,14,8,7]
。运行一个heapify
后,它将变成[16,14,10,8,7,9,3,2,4]
。现在 heapsort
的第一次迭代将交换 16 和 4,导致 [4,14,10,8,7,9,3,2,16]
。因为这现在已经将新堆的根 [4,14,10,8,7,9,3,2]
呈现为,嗯,未堆,(14 和 10 都更大比 4),运行另一个 heapify
来生成 [14,8,10,4,7,9,3,2]
。现在 14 是根,将它与 2 交换以产生 [2,8,10,4,7,9,3,14]
,从而使数组当前为 [2,8, 10,4,7,9,3,14,16]
。我们再次发现 2 未堆,因此再次执行 heapify
使堆成为 [10,8,9,4,7,2,3]
。然后将 10 与 3 交换,使数组成为 [3,8,9,4,7,2,3,10,14,16]
。我的观点是,我们可以从第一个 heapification
中看出,因为 10 和 14 在 16 之后,所以我们可以从第一个 heapification
中看出,它们是第二大和第三大元素(反之亦然)。因此,在比较它们之后(如果它们已经排序,14 在 10 之前),我将所有 (16,14,10)
替换为 (3,2,4)
,生成数组 [3,2,4,8,7,9,16,14,10]
。这将我们简化为与另外两个 heapification
之后的情况类似的情况 - [3,8,9,4,7,2,3,10,14,16]
最初,与现在的 [3,2,4,8,7,9,16,14,10]
相比。两者现在都需要进一步heapification
,但是第二种方法让我们通过两个元素(14 和 10)之间的比较直接到达这个关头。
最佳答案
堆的第二大元素出现在第二或第三个位置,但第三大元素可以出现在更下方的深度 2 处。(参见 http://en.wikipedia.org/wiki/Heap_(data_structure) 中的图)。此外,将前三个元素与后三个元素交换后,heapify 方法将首先对根的第一个子树进行堆化,然后是根的第二个子树,然后是整棵树。因此,此操作的总成本接近于将顶部元素与最后一个元素交换并调用 heapify 的成本的三倍。所以这样做你不会有任何收获。
关于algorithm - Heapsort 的这种优化有多值得?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12502748/
我正在生成代码,其中我恰好将 n 个单词从一个内存位置复制到另一个非重叠内存位置。 n 是静态已知的。 目前,我发出大量加载指令,然后是大量存储指令,但我怀疑从 n 的某个值开始,调用 memcpy会
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 4 年前。 Improve this ques
用例如下: 我有一张 map ,其中将插入一些键/值。 该程序将查询该 map ,但是在第一个查询之后,我可以保证该 map 将完全不会被修改。 因为查询的结果完全是输入的函数,所以在查询方法上放置属
Helo 伙计们,我尝试使用 Refs 并在他的内部提供 this.setState 但它给出: Maximum update depth exceeded. This can happen when
在检查事件时,使用带有 switch 或 if 的代码块是很常见的事情。如果变得简单,它可以是干净的代码,但似乎仍然有比需要更多的行,并且可以使用 lambda 进行简化。 用 if 阻止: if(a
Amazon 最近宣布在其 RDS 产品线中支持 Oracle: http://aws.amazon.com/rds/oracle/ 我想知道是否有人使用过它,或者是否有令人信服的理由将我的数据从 M
我是一名优秀的程序员,十分优秀!