当左右子节点等于且小于父节点时,我该怎么做才能从最小堆中删除一个值

时间:2013-10-17 02:02:40

标签: c heap min

当左右子节点等于且小于父节点时,如何从min heap中删除值。例如,我的最小堆的根上有一个值0,并希望将其删除。我将0与我的向量的最后一个元素(值= 12)交换,之后,我需要运行将向量再次转换为最小堆的函数(min-heapfy),但在我的例子中我交换了0 12,现在12是根,0很快就会返回。我必须与左子(1)或右子(1)交换12,我怎么知道这个数字1中的哪一个先输入?

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

int left(int i){
    return 2*i;
}

int right(int i){
    return 2*i +1;
}

void swap_pos(int *vi, int *vm){
    int aux;
    aux = *vi;
    *vi = *vm;
    *vm = aux;
}

void heapify(int *v, int i,int heap_size){ 
    int l,r,menor_ind = i;
    l = left(i); 
    r = right(i); 
    if(l<=heap_size && v[l]<v[i]) menor_ind = l;
    if(r<=heap_size && v[r]<v[menor_ind]) menor_ind = r;
    if(menor_ind!= i){
        swap_pos(&v[i],&v[menor_ind]);
        heapify(v,menor_ind,heap_size);
    }
}

void build_min_heap(int v[],int heap_size){
    int i;
    for(i=heap_size/2; i>=1; i--){
        heapify(v,i,heap_size);
    }
}

int extract(int *v, int *heap_size){
    int ret = v[1];
    if(*heap_size==0) return -1;// erro
    swap_pos(&v[*heap_size],&v[1]); // swap root with the last element
    (*heap_size)--;
    heapify(v,1,*heap_size);
    return ret;
}

void heap_sort(int *v, int *heap_size){
    while(*heap_size>=2){
        swap_pos(&v[1],&v[*heap_size]);
        (*heap_size)--;
        heapify(v,1,*heap_size);
    }
}

int main(void){
    int heap_size = 9;
    int i, v[] = {-1,6,12,3,1,5,0,1,9,7};
    build_min_heap(v,heap_size);
    printf("%d\n",extract(v,&heap_size));
    //heap_sort(v,&heap_size);
    for(i=1; i<=heap_size; i++){
        printf("%d ",v[i]);
    }
    return 0;
}

1 个答案:

答案 0 :(得分:0)

就堆而言,11是相等的。 (的确,这通常是正确的。)因此,1成为新的根并不重要。 12将渗透到堆中,直到它找到一些休息的地方,可能在边缘但不一定。没有任何东西需要它回到它来自的地方,并且很可能它不会。

为什么您认为您提供的代码不正确?