我已经尝试在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;
}
提前谢谢!
答案 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;
}