Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm 构建堆的改进算法_Algorithm_Heap - Fatal编程技术网

Algorithm 构建堆的改进算法

Algorithm 构建堆的改进算法,algorithm,heap,Algorithm,Heap,我对编程非常陌生,我正试图理解关于堆排序的某个问题。在我正在读的一本书中,有一个构建最大堆的改进算法,它是: BuildHeap(A) A.heap-size = 1 for i = 2 to A.length Heap-Insert(A, A[i]) 根据我的理解,这个算法接受一个数组,将堆的大小定义为1,然后从2迭代到数组的总长度,然后将值插入堆中 但这将如何构建一个最大堆呢?如果我有一个[4,7,2,3,9,1]数组,那么算法不是从值2开始,然后简单地将A

我对编程非常陌生,我正试图理解关于堆排序的某个问题。在我正在读的一本书中,有一个构建最大堆的改进算法,它是:

BuildHeap(A)
    A.heap-size = 1
    for i = 2 to A.length
        Heap-Insert(A, A[i])
根据我的理解,这个算法接受一个数组,将堆的大小定义为1,然后从2迭代到数组的总长度,然后将值插入堆中

但这将如何构建一个最大堆呢?如果我有一个[4,7,2,3,9,1]数组,那么算法不是从值2开始,然后简单地将A[2]到A.length的所有值添加到堆中,而不实际构建最大堆吗

我不明白
堆大小=1
在算法中除了限制堆的总大小之外,还有什么作用。我不知道如何构建最大堆

根据书中所述,普通最大堆的工作原理是首先将每个数组值插入堆中,然后从a/2位置开始,然后向后工作,并通过调用
max Heapify
交换大于当前评估值的值


既然没有
max Heapify(A,max)
调用,而是有一个
heap insert(A,A[i])
,那么这个max heap是如何工作的呢?

首先,这个问题不是关于堆排序的,它只是堆的一个应用程序。您正在询问堆的构造

您提供的伪代码确实是构建堆的另一种(而且效率较低)方法,这实际上是许多人在不知道Floyd的标准算法时会想到的算法

那么看看代码:

BuildHeap(A)
    A.heap-size = 1
    for i = 2 to A.length
        Heap-Insert(A, A[i])
该算法的大部分逻辑都是在
Heap Insert
函数中实现的,该函数不仅仅是对数组的简单“追加”:它的作用远不止于此。将隐藏算法描述如下:

  • 将元素添加到堆最左边的开放空间的底层
  • 将添加的元素与其父元素进行比较;如果顺序正确,请停止
  • 如果不是,则将该元素与其父元素交换并返回到上一步
  • 你在问题中写道:

    没有Max Heapify(A,最大)

    事实上,如果您在使用堆之前就已经知道最大值是多少,那就太简单了。您需要首先在堆中插入一个值(任意值),并让堆发挥其魔力(在
    heap insert
    中),以确保最大值最终位于数组
    a
    的第一(顶部)位置,即
    a[1]

    因此,引用的算法的第一步很重要:
    Heap Insert
    希望在末尾插入新值

    让我们看一下示例[4,7,2,3,9,1],然后放置一个管道符号来指示堆的结束。开始时,堆大小为1,因此我们有:

    4 | 7   2   3   9   1
    
    让我们在右侧展示一个更具视觉吸引力的二叉树——它只有一个根元素:

    4 | 7   2   3   9   1                  4
    
    然后我们调用
    堆插入(A,A[2])
    ,这就是
    堆插入(A,7)
    Heap Insert的实现将增加堆的大小,并将该值放入最后一个插槽中,因此我们得到:

    4   7 | 2   3   9   1                  4
                                          /
                                         7
    
    7   4 | 2   3   9   1                   7
                                           /
                                          4
    
    堆插入
    尚未完成——这只是它执行的第一步。现在它“冒泡”了,下面是引用的算法的第2步和第3步,我们得到:

    4   7 | 2   3   9   1                  4
                                          /
                                         7
    
    7   4 | 2   3   9   1                   7
                                           /
                                          4
    
    在伪代码循环的第二次迭代中,我们调用
    堆插入(A,2)
    ,因此
    堆插入执行其第一步:

    7   4   2 | 3   9   1                   7
                                           / \
                                          4   2
    
    …并发现在执行步骤2和3时无需更改任何内容

    我们继续插入3:

    7   4   2   3 | 9   1                   7
                                           / \
                                          4   2
                                         /
                                        3
    
    …同样,没有什么需要更改,因为3小于4(请记住
    A[2]
    A[4]
    的父级

    我们继续插入9:

    7   4   2   3   9 | 1                   7
                                           / \
                                          4   2
                                         / \
                                        3   9
    
    这里是9>4,也是9>7,因此
    Heap Insert
    将进一步将
    A
    修改为:

    9   7   2   3   4 | 1                   9
                                           / \
                                          7   2
                                         / \
                                        3   4
    
    还有一个:

    9   7   2   3   4   1                   9
                                          /   \
                                         7     2
                                        / \   /
                                       3   4 1
    

    堆插入
    与1<2无关。

    堆插入将堆的大小增加1(A.length+=1)并确保通过在正确的位置插入新元素来维护heap属性。如果它将堆的大小增加1,那么它不只是将数组中的下一个值添加到堆中,而实际上不使其成为max heap吗?因此,如果上面使用了数组,数组不是先从值2开始,然后再增加最大值吗按1堆,并在堆中的2下添加3?在伪代码中,通常习惯使用基于1的索引,因此A[2]是A中的第二个元素,所以是7。@trincot如果我错了,请纠正我,但算法首先查看数组的第二个到最后一个条目,然后简单地添加最大的元素?Heap insert是否隐式选择了数组中最大的元素?我只是想了解在这段小代码中实际选择的大元素在哪里数组中的est元素。好吧,Heap Insert例程完成了在其正确位置冒泡出最右边的值的所有艰苦工作。请注意,您的标题有误导性:这不是heapsort,而是构建堆。谢谢,这是一个非常有用的方法!