了解堆(优先级队列)中的向上和向下渗透函数

Understanding the percolate up and down functions in Heaps (Priority Queues)

本文关键字:函数 渗透 优先级 队列 了解      更新时间:2023-10-16

我在最小堆(顶部最小的键)中上下渗透的代码遇到了一些问题。我最大的抱怨是这两个代码片段的 for 循环,这导致我不理解其余的代码......

int hole = ++currentSize;
Comparable copy = x;
array[ 0 ] = std::move( copy ); //in the books implementation the zero 
//index is kept empty, is this to create a temporary place for the added element?
for( ; x < array[ hole / 2 ]; hole /= 2 ) //my biggest problem is understanding this for loop!!!
    array[ hole ] = std::move( array[ hole / 2 ] ); //what does this do?
array[ hole ] = std::move( array[ 0 ] );

我不明白这里的 for 循环。这可能与关系有关,例如 i'th 索引的父级在 i/2 中等等,但我对此一无所知。这是将元素插入堆。感谢在布置代码含义方面的任何帮助。

然后是findMin方法的渗透,我再次不理解代码。

/**
    * Internal method to percolate down in the heap.
    * hole is the index at which the percolate begins.
    */
void percolateDown( int hole )
{
    int child;
    Comparable tmp = std::move( array[ hole ] );
    for( ; hole * 2 <= currentSize; hole = child ) //not clear with this for loop!!!
{
    child = hole * 2;
    if( child != currentSize && array[ child + 1 ] < array[ child ] )
    ++child;
    if( array[ child ] < tmp )
    array[ hole ] = std::move( array[ child ] );
    else
        break;
    }
    array[ hole ] = std::move( tmp );
    } //somewhat understood, except the for loop...

主要是for循环,还有代码的哪一部分做什么?如果问题中有任何业余内容,请道歉。

正如你所说:元素 i 的父级位于 i/2 .代码的作用是插入一个"孔",这将是放置新元素的位置。for 循环中的行:

array[ hole ] = std::move( array[ hole / 2 ] );

正在将父项移动到子项的位置(即"孔")。所以我们基本上要做的是以下几点

while (element being moved up < parent)
    move parent to current index
    current index = index of parent
place element at current index

另一段代码则相反。这有点复杂,因为虽然每个元素只有一个父元素,但它可能有两个子元素。第一个位于i * 2,第二个位于i * 2 + 1。首先,我们检查元素是否甚至有子元素(child != currentSize)。我们只想在孩子更小的情况下将父母与孩子交换。所以我们看看哪个孩子最小(array[ child + 1 ] < array[ child ])。我们将那个孩子与它的父母进行比较:如果它更小,我们交换它们并继续,否则我们就完成了。最后,我们将要移回的元素放在"孔"中。