0

我正在尝试使用数组在 C 中创建二进制最小堆。我编写了代码并多次尝试用“笔和纸”执行它,它似乎有效。你能帮我理解为什么它会失败吗?

这是库代码:

#include <stdlib.h>

void swapInt(int *a, int *b) {
    int aux = *a;
    *a = *b;
    *b = aux;
}

typedef struct intHeapArray {
    int *array;
    int size;
} IntHeapArray;

IntHeapArray newIntHeapArray (int dim) {
    IntHeapArray new;
    new.array = (int*) malloc(sizeof(int)*dim);
    new.size = 0;
    return new;
}

int findFather (int index) {
    return (index - 1) / 2;
}

int findLeftChild (int index) {
    return index * 2 + 1;
}

int findRightChild (int index) {
    return index * 2 + 2;
}

int minFatherChilds (IntHeapArray h, int index) {
    int leftchild = findLeftChild(index);
    int rightchild = findRightChild(index);
    if (rightchild >= h.size)
        rightchild = leftchild;
    if (h.array[index] > h.array[leftchild])
        index = leftchild;
    if (h.array[index] > h.array[rightchild])
        index = rightchild;
    return index;
}

void reorganizeIntHeapArray (IntHeapArray *h, int index) {
    int father, leftchild, child;
    father = findFather(index);
    while (index > 0 && h->array[index] < h->array[father]) {
        swapInt(&h->array[index], &h->array[father]);
        index = father;
    }
    leftchild = findLeftChild(index);
    while (leftchild < h->size && index != minFatherChilds(*h, index)) {
        child = minFatherChilds(*h, index);
        swapInt(&h->array[index], &h->array[child]);
        index = child;
    }
}

void enqueueIntHeapArray (IntHeapArray *h, int val) {
    h->array[h->size] = val;
    h->size++;
    reorganizeIntHeapArray(h, h->size - 1);
}

这是来自主脚本的调用:

#include <stdio.h>
#include "heap.h"

void printIntArray (int *a, int dim) {
    int i;
    printf("[");
    for (i = 0; i < dim - 1; i++)
        printf("%d, ", a[i]);
    printf("%d]\n", a[dim-1]);
}

int main () {
    IntHeapArray h;
    int n, i, val;

    printf("How many value would you like to add to the heap? ");
    scanf("%d", &n);

    h = newIntHeapArray(n);

    printf("Insert values:\n");
    for (i = 0; i < n; i++) {
        scanf("%d", &val);
        enqueueIntHeapArray(&h, val);
    }

    printf("This is your heap:\n");
    printIntArray(h.array, h.size);

    return 0;
}

代码编译。试试这个输入:6 3 8 9 2 0. 它将打印:[3, 2, 0, 9, 6, 8]这显然是错误的。但我真的不明白我错在哪里。

4

1 回答 1

1

我发现了错误。重组堆函数必须更改为:

void reorganizeIntHeapArray (IntHeapArray *h, int index) {
    int father, leftchild, child;
    father = findFather(index);
    while (index > 0 && h->array[index] < h->array[father]) {
        swapInt(&h->array[index], &h->array[father]);
        index = father;
        father = findFather(index);
    }
    leftchild = findLeftChild(index);
    while (leftchild < h->size && index != minFatherChilds(*h, index)) {
        child = minFatherChilds(*h, index);
        swapInt(&h->array[index], &h->array[child]);
        index = child;
        leftchild = findLeftChild(index);
    }
}

我只更新了索引值而不是父亲的值。所以在第一次切换之后,它会将 h->array[index] 与自身进行比较,而不是与它的新父亲进行比较。

编辑:它仍然是错误的。我在第二个中做了同样的错误,我在第一个中犯了同样的错误。我没有更新 leftchild 值。现在应该是正确的。

于 2012-06-10T13:44:18.577 回答