简体   繁体   English

构建堆时间复杂度最坏情况vs上限/上限

[英]build heap time complexity worst case vs upper bound / tight upper bound

HERE it is said that the worst case time complexity of building a heap is O(nlogn) but upper bound is O(n). 这里据说,建立堆的最坏情况下的时间复杂度是O(nlogn),但是上限是O(n)。

How is a upper bound different from worst case time complexity and when one makes more sense over other. 上限与最坏情况下的时间复杂度有何不同?何时比其他情况更有意义。 And is tight upper bound any different ? 紧密上限有什么不同吗?

Building a heap (also called Heapify ) is always O(n), regardless of the input distribution or the branching factor of the heap ( binary, ternary heaps ...). 不管输入分布或堆的分支因子( 二进制,三元堆 ...)如何,构建堆(也称为Heapify始终为 O(n)。

You misread the provided link, it states: (emphasis is mine) 您误读了提供的链接,它指出:(强调是我的)

Although the worst case complexity looks like O(nLogn), upper bound of time complexity is O(n). 尽管最坏情况下的复杂度看起来像 O(nLogn),但时间复杂度的上限是O(n)。

Basically, how does heapify work? 基本上,heapify如何工作? (For clarity's sake I'll assume we are using binary heaps) (为清楚起见,我假设我们正在使用二进制堆)

First let's recall what is the heap condition for a binary heap (using an array A): 首先,让我们回顾一下二进制堆的堆条件是什么(使用数组A):

For any i ∈ [0, [N/2], A[i] ≤ A[2i+1] AND A[i] ≤ A[2i+2] 对于任何i∈[0,[N / 2],A [i]≤A [2i + 1] A [i]≤A [2i + 2]

Note: You will usually find the same condition expressed for an array starting at index 1. In that case you just have to "remove" 1, ie. 注意:通常,您会发现从索引1开始的数组所表达的条件相同。在这种情况下,您只需“删除” 1,即。 2i+1 becomes 2i and 2i+2 becomes 2i+1. 2i + 1变成2i,2i + 2变成2i + 1。

Why is this condition limited to the first half of the heap? 为什么这种情况仅限于堆的前半部分? Simple, for any i > N/2, neither 2i+1 nor 2i+2 are valid indexes. 很简单,对于任何i> N / 2,2i + 1和2i + 2都不是有效索引。

HEAPIFY HEAPIFY
Input: An array of N elements 输入: N个元素的数组
Output: An array of the same N elements that enforces the heap condition 输出:强制执行堆条件的相同N个元素的数组

void sink(int [] A, int i, int n) {
    int highest = 2*i+1;
    if (2*i+1 >= n)
        return;
    if (2*i+2 < n && A[2*i+2] > A[highest])
        ++highest;
    if (A[i] < A[highest]) {
        swap(A, i, highest);
        sink(A, highest, n);
    }
}

void heapify(int [] A, int n) {
    for (int i = n/2; i >= 0; --i) {
        sink(A, i, n);
    }
}

Suppose we have a complete binary heap , such a heap contains exactly N = 2 h+1 - 1 elements for a given integer h >= 0. View the heap as a tree. 假设我们有一个完整的二进制堆 ,对于给定的整数h> = 0,该堆恰好包含N = 2 h + 1-1个元素。将其视为树。 Index 0 is the root of the tree (height 1), indexes 1,2 are the children of this root (height 0), and so on. 索引0是树的根(高度1),索引1,2是该根的子代(高度0),依此类推。 The height of the tree is the integer h. 树的高度是整数h。

The algorithm starts at height h-1. 该算法从高度h-1开始。 The 2 h-1 elements at height h-1 can be moved at most once while sinking them down. 高度为h-1的2个h-1元素在下沉时最多可以移动一次。 Then, the 2 h-2 elements at height h-2 can trigger at most 2 swaps per element... The root (2 0 element of height 0) can trigger at most h swaps. 然后,高度为h-2的2个h-2元素每个元素最多可触发2个交换...根(高度为0的2 0个元素)最多可触发h个交换。 In the end, the maximum number of swaps to build the heap is : 最后,建立堆的最大交换数为:

MaxSwap = sum(k=0..h-1, 2 k .(hk)) = 2 h+1 - h - 2 ≤ 2 h+1 - 1 = N MaxSwap = sum(k = 0..h-1,2 k 。(hk)) = 2 h + 1 -h- 2≤2 h + 1-1 = N

The maximum number of comparisons to build the heap is twice the maximum number of swaps. 生成堆的最大比较次数是最大交换次数的两倍。 For any "incomplete" heap, ie. 对于任何“不完整”的堆,即 2 h ≤ N < 2 h+1 - 1, the reasoning still holds. 2个小时 ≤Ñ<2个小时+ 1 - 1,推理仍然成立。

Conclusion: Heapify is O(N) where N is the size of the heap. 结论:Heapify O(N),其中N是堆的大小。


Bonus 奖金

A running Java example that builds a Maxheap from an input array : here 一个正在运行的Java示例,它从输入数组构建一个Maxheap: 这里

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM