堆更新顺序

发布于 2025-01-14 20:20:16 字数 1407 浏览 3 评论 0原文

这是堆排序算法的工作代码,我的问题是,在堆创建中,我是否将代码中的条件与

for ( int i = 0 ; i  < dim/2-1; i ++)

我认为是 for 循环但顺序相反的条件交换,并且我认为更新堆的过程完全相同(在我的想法是,我们要更新从 0 到数组末尾的每个索引的堆条件),为什么该算法不再起作用?其他条件写错了,还是算法只是设计用于减少索引 i?谢谢

#include <stdio.h>

void Scambia( int *px, int *py);

void  Aggiornaheap( int *pa, int i, int j);

int main(void)
{
    int a[256];
    int n;
    int dim = 0;
    
    // Lettura dell’input da tastiera
    while (scanf("%d\n", &n) == 1)
    {
        a[dim] = n;
        dim++;
    }

    // heap creation
    for ( int i = dim/2-1 ; i  >= 0; i --)
    {
    Aggiornaheap(a, i, dim);
    }

    //Heapsort
    for ( int i = dim-1; i  >= 0; i --)
    {
    Scambia(&a[0], &a[i]);
    Aggiornaheap(a, 0, i-1);
    }

    for ( int i = 0; i < dim; i++)
        printf("%d ", a[i]);
    printf("\n");

return 0;
}

void Scambia( int *px, int *py)
{
    int temp;

    temp = *px;
    *px = *py;
    *py = temp;

}

void  Aggiornaheap( int *pa, int i, int j)
{
    int k;
    if ( 2*i == j )
    {
        if ( pa[i] < pa[j])
        Scambia(&pa[i], &pa[j]);
    }

    if ( 2*i < j )
    {
        if ( pa[2*i] > pa[2*i+1] )
            k = 2*i;
        else k = 2*i+1;
    
        if ( pa[i] < pa[k])
        {
            Scambia(&pa[i], &pa[k]);
            Aggiornaheap(pa, k, j);
        }
    }
}

here's a working code for heapsort algorithm, my question is if in heap creation I swap the condition in the code with

for ( int i = 0 ; i  < dim/2-1; i ++)

that I think it's the for cycle but in reverse order and I think that the process of updating the heap is quite the same (in my head we go trough updating the heap condition for every index from 0 to the end of the array),why the algorithm won't work anymore? It's wrong written the other condition or simply the algorithm is designed to work decreasing the index i? Thank you

#include <stdio.h>

void Scambia( int *px, int *py);

void  Aggiornaheap( int *pa, int i, int j);

int main(void)
{
    int a[256];
    int n;
    int dim = 0;
    
    // Lettura dell’input da tastiera
    while (scanf("%d\n", &n) == 1)
    {
        a[dim] = n;
        dim++;
    }

    // heap creation
    for ( int i = dim/2-1 ; i  >= 0; i --)
    {
    Aggiornaheap(a, i, dim);
    }

    //Heapsort
    for ( int i = dim-1; i  >= 0; i --)
    {
    Scambia(&a[0], &a[i]);
    Aggiornaheap(a, 0, i-1);
    }

    for ( int i = 0; i < dim; i++)
        printf("%d ", a[i]);
    printf("\n");

return 0;
}

void Scambia( int *px, int *py)
{
    int temp;

    temp = *px;
    *px = *py;
    *py = temp;

}

void  Aggiornaheap( int *pa, int i, int j)
{
    int k;
    if ( 2*i == j )
    {
        if ( pa[i] < pa[j])
        Scambia(&pa[i], &pa[j]);
    }

    if ( 2*i < j )
    {
        if ( pa[2*i] > pa[2*i+1] )
            k = 2*i;
        else k = 2*i+1;
    
        if ( pa[i] < pa[k])
        {
            Scambia(&pa[i], &pa[k]);
            Aggiornaheap(pa, k, j);
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

时间你老了 2025-01-21 20:20:16

必须以相反的顺序访问节点。如果您更改该顺序,该算法将无法正确完成其工作。

以需要堆化为最小堆的输入树为例:[2,4,3,1],可以将其可视化如下:

            2
           / \
          4   3
         /
        1

然后注意值 1 不可能冒泡到顶部,当您更改 for 循环以继续前进时。我们来试试这个吧。当 i==0 时,没有任何内容被交换,因为 2 小于它的子元素。当i==1时,4将被1交换,然后循环结束。显然,这还没有创建有效的堆。

然而,如果我们从 i==1 开始,这会触发 1 与 4 的交换,并且只有然后i==0,那么我们将再次交换 1 以向上移动:

            1
           / \
          2   3
         /
        4

关于您的代码的一条评论。看起来您使用的是零索引数组,根元素为 0,但在这种情况下,子元素位于 i*2+1i*2+2 >,就像我们在您的代码中看到的那样。

It is necessary that the nodes are visited in reverse order. The algorithm will not do its job correctly if you change that order.

Take for instance this input tree that needs to be heapified into a min-heap: [2,4,3,1], which can be visualised as follows:

            2
           / \
          4   3
         /
        1

Then note how it will be impossible for the 1 value to bubble to the top, when you alter the for loop to go forward. Let's just try this. When i==0 nothing is swapped, because 2 is less than its children. When i==1 then 4 will be swapped with 1, and then the loop has finished. Clearly, this has not created a valid heap.

If however we start with i==1, which triggers the swap of 1 with 4, and only then have i==0, then we will again swap 1 to move up:

            1
           / \
          2   3
         /
        4

One comment about your code. It looks like you work with zero-indexed arrays, with the root element at 0, but in that case the children are at i*2+1 and i*2+2, not one less like we see in your code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文