删除堆的根无效

时间:2018-04-15 15:23:13

标签: c heap

我已经尝试在C中实现与堆相关的函数,我偶然发现了删除堆根函数的问题。 当堆只有一个元素时,该函数不会删除任何内容,即使我明确表示如果只有一个元素,则堆变为NULL。 下面我已经发布了我创建的所有函数的代码(可能其他函数有问题,但我似乎不太可能)。主要问题是deleteRoot函数。

#include <stdio.h>
#include <stdlib.h>

typedef struct Heap Heap;
struct Heap
{
    Heap *left;
    Heap *right;
    Heap *parent;
    int value;
};


Heap *newHeap(int x)
{
    Heap *t = malloc(sizeof(Heap));
    t->value = x;
    t->left = NULL;
    t->right = NULL;
    t->parent = NULL;
    return t;
}

void printHeap(Heap *h)
{
    if(h!=NULL)
    {
        printf("Value %d (",h->value);
        printHeap(h->left);
        printf(")");
        printf("(");
        printHeap(h->right);
        printf(")");
    }
}

int getHeapMinDepth(Heap *h)
{

    if(h == NULL) return 0;
    int leftdepth = getHeapMinDepth(h->left);
    int rightdepth = getHeapMinDepth(h->right);
    int mindepth = (leftdepth < rightdepth) ? leftdepth : rightdepth;
    return mindepth + 1;
}

int getHeapMaxDepth(Heap *h)
{

    if(h == NULL) return 0;
    int leftdepth = getHeapMaxDepth(h->left);
    int rightdepth = getHeapMaxDepth(h->right);
    int maxdepth = (leftdepth > rightdepth) ? leftdepth : rightdepth;
    return maxdepth + 1;
}

void bubbleUp(Heap *h)
{
    int aux;
    if(h->parent != NULL && h != NULL)
    {
        if(h->parent->value < h->value)
        {
            aux = h->value;
            h->value = h->parent->value;
            h->parent->value = aux;
            bubbleUp(h->parent);
        }

    }

}

void bubbleDown(Heap *h)
{
    int aux;
    if(h != NULL)
    {
        if(h->left != NULL && h->left->value > h->value)
        {
            aux = h->value;
            h->value = h->left->value;
            h->left->value = aux;
            bubbleDown(h->left);

        }

    else if(h->right != NULL && h->right->value > h->value)
    {
        aux = h->value;
        h->value = h->right->value;
        h->right->value = aux;
        bubbleDown(h->right);

    }

    }

}

void addElement(Heap *h ,int x)
{
    if(h == NULL) h = newHeap(x);
    else if(h->left == NULL)
    {
        h->left = newHeap(x);
        h->left->parent = h;
        bubbleUp(h->left);
    }
    else if(h->right == NULL)
    {
        h->right = newHeap(x);
        h->right->parent = h;
        bubbleUp(h->right);
    }
    else if(getHeapMinDepth(h->left) <= getHeapMinDepth(h->right)) addElement(h->left,x);
    else addElement(h->right,x);

}

void deleteRoot(Heap *h)
{
    Heap *auxheap = h;

    if(h!=NULL && h->left == NULL && h->right == NULL) h = NULL;

    else if(h!=NULL)
    {

        while(auxheap ->left != NULL || auxheap->right != NULL)
        {
            if(getHeapMaxDepth(auxheap->left) > getHeapMaxDepth(auxheap->right)) auxheap = auxheap->left;
            else auxheap = auxheap->right;
        }

        h->value = auxheap->value;
        auxheap->value = -1;
        auxheap = auxheap->parent;
        if(auxheap->right != NULL && auxheap->right->value == -1)   auxheap->right = NULL;
        else  auxheap->left = NULL;
        bubbleDown(h);


    }


}

int main()
{
    int i;
    Heap *h = newHeap(2);
    deleteRoot(h);
    addElement(h,12);
    addElement(h,5);
    addElement(h,7);
    addElement(h,15);
    printHeap(h);
    return  0;
}

提前谢谢!

1 个答案:

答案 0 :(得分:2)

为了避免C中的按值调用问题,请使用指向指针的指针作为根删除函数的参数。

void deleteRoot(Heap **h)
{
    /* assuming that h is not NULL, which is guaranteed with "&something" */
    if((*h)!=NULL && (*h)->left == NULL && (*h)->right == NULL) *h = NULL;
    /* ... */
}

int main()
{
    int i;
    Heap *h = newHeap(2);
    deleteRoot(&h);
    /* ... */
    return  0;
}