它並不甚至第三個數字
這部分之前進入while循環可以回答。你的循環不會去,直到i
等於或大於2 ...
while (i > 1 && h->array[parent]< key) {
^^^^^
下面是設置i
的代碼。
h->size = h->size+1;
int i = h->size-1;
該代碼更易於理解,像這樣:
int i = h->size;
h->size++;
第一次通過,i
將是0(假設h->size
被初始化爲0,則沒有表現出你的堆初始化代碼)。第二次將是1.第三次將是2,然後最後循環可以運行。
我猜你希望i >= 1
在while循環中,所以它會繼續第二次調用。
至於爲什麼它不工作,首要的問題是你忘在循環改變parent
。
/* i and parent initialized */
int i=h->size-1;
...
int parent=(i-1)/2;
while (i>1 && h->array[parent]< key) {
h->array[i]= h->array[parent];
/* i is changed, but where's parent? */
i = parent;
h->array[i]=key;
}
下面是它應該的樣子。我已將i
更改爲僅用於循環索引的更多描述性new
。
/* new and parent initialized */
int new = h->size;
...
int parent = (new-1)/2;
while(new != 0 && h->array[parent] < key) {
h->array[new] = h->array[parent];
h->array[parent] = key;
/* new AND parent changed */
new = parent;
parent = (new-1)/2;
}
下面是完整的代碼,加上我做了堆的大小動態的,因爲固定大小的結構是最好的避免了柺杖。
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int size;
int max_size;
int *array;
} heap;
#define INIT_HEAP_SIZE 4
static heap *heap_init() {
heap *h = calloc(1, sizeof(heap));
h->max_size = INIT_HEAP_SIZE;
h->array = calloc(h->max_size, sizeof(int));
return h;
}
static void heap_destroy(heap *h) {
free(h->array);
free(h);
}
static void heap_grow(heap *h) {
h->max_size *= 2;
h->array = realloc(h->array, h->max_size * sizeof(int));
}
static void heap_insert(heap* h, int key) {
if (h->size >= h->max_size) {
heap_grow(h);
}
int new = h->size;
h->size++;
h->array[new] = key;
int parent = (new-1)/2;
while(new != 0 && h->array[parent] < key) {
h->array[new] = h->array[parent];
h->array[parent] = key;
new = parent;
parent = (new-1)/2;
}
return;
}
int main(void) {
heap *h = heap_init();
heap_insert(h, 23);
heap_insert(h, 11);
heap_insert(h, 42);
heap_insert(h, 5);
heap_insert(h, 99);
for(int i = 0; i < h->size; i++) {
printf("%d: %d\n", i, h->array[i]);
}
heap_destroy(h);
}
請格式化/縮進您的代碼。有例如最後缺少'}。 – jofel
我已經縮進了......但實際上不止一個缺失的大括號。這個函數成功返回什麼?哪裏? – kdopen
對不起,你修好了。它不會返回任何東西,它只是填充已在主函數中聲明的堆。 – Meowzen