/*testheap.c*/ #include <stdio.h> #include <time.h> #include <assert.h> #include "heap.h" #define ARRAY_MAX_LEN 1000 int disp_heap(struct heap_root *root) { int i; printf("disp_heap:"); for(i = 0; i < root->offset; i++) { printf("%d ",(root->root + i)->d); } printf("\n"); } int compare(int x, int y) { return (x-y); } int main() { srand((unsigned int)time(NULL)); int a[ARRAY_MAX_LEN]; int a_len = sizeof(a)/sizeof(int); int it = 10000; while(it--) { int aj = a_len; while(aj--) { a[aj]=rand()%ARRAY_MAX_LEN; } struct heap_root *h_root; h_root = make_heap(ARRAY_MAX_LEN,compare); int i; int w_len = rand()%ARRAY_MAX_LEN ; for(i = 0; i < w_len; i++) { struct heap_node node; node.d = a[i]; push_heap(h_root, node); } //printf("\nh_root->offset=%d\n", h_root->offset); //disp_heap(h_root); //printf("\n"); int pre = ARRAY_MAX_LEN + 10; for(i = 0; i < w_len; i++) { struct heap_node node; assert(pre >= node.d); pop_heap(h_root, &node); pre = node.d; //printf("%d ", node.d); //disp_heap(h_root); } //printf("\n"); destroy_heap(h_root); } return 0; }
/*heap.h*/ #include <stdlib.h> #include <stdio.h> typedef int elem_t; struct heap_node{ elem_t d; }; struct heap_root{ struct heap_node *root; int offset; int (*compare)(); int heap_max; }; struct heap_root* make_heap(int size, int (*compare_fun)()); int destroy_heap(struct heap_root *heap_head); int push_heap(struct heap_root *root, struct heap_node node); int pop_heap(struct heap_root *root, struct heap_node *node);
/*heap.c*/ #include "heap.h" struct heap_root* make_heap(int size, int (*compare_fun)()) { if(NULL == compare_fun || size <= 0) { return NULL; } struct heap_node *root = calloc(size, sizeof(struct heap_node)); struct heap_root *heap_head = calloc(1, sizeof(struct heap_root)); heap_head->root = root; heap_head->offset = 0; heap_head->compare = compare_fun; heap_head->heap_max = size; return heap_head; } int destroy_heap(struct heap_root *heap_head) { free(heap_head->root); free(heap_head); return 0; } int push_heap(struct heap_root *root, struct heap_node node) { if(root->offset >= root->heap_max ) { printf("ERROR:Out Of Bound\n"); return -1; } struct heap_node *top = root->root; struct heap_node *cur = top + root->offset; *cur = node; int cur_i = root->offset; int par_i = (cur_i - 1)/2; int ret; while(cur_i > 0) { ret = compare(top[cur_i], top[par_i]) > 0; if(ret > 0) { swap(&top[cur_i], &top[par_i]); } cur_i = par_i; par_i = (cur_i - 1)/2; } root->offset++; //printf("push:top=%d\n",top->d); return 0; } int pop_heap(struct heap_root *root, struct heap_node *node) { if(root->offset <= 0 || root->offset >= root->heap_max) { printf("ERROR:Out Of Bound\n"); return -1; } struct heap_node *top = root->root; *node = *top; root->offset--; *top = *(top + root->offset ); //printf("__node.d=%d\n", node->d); int ret; int cur_i = 0;//current node index int lch_i = cur_i*2 + 1;//left child node index int rch_i = (cur_i + 1)*2;//right child node index int index; while(lch_i < root->offset) { //printf("cur:%d lch_i:%d\n", cur_i, lch_i); index = lch_i; if(rch_i < root->offset) { ret = compare(top[rch_i], top[lch_i]); if(ret > 0) { index = rch_i; } } ret = compare(top[index], top[cur_i]); if(ret > 0) { swap(&top[cur_i], &top[index]); cur_i = index; } else { break; } lch_i = cur_i*2 + 1;//left child node index rch_i = (cur_i + 1)*2;//right child node index } return 0; } int swap(struct heap_node *x, struct heap_node *y) { struct heap_node tmp = *x; *x = *y; *y = tmp; return 0; }
Makefile
CC=gcc Cflag=-Wall -g Obj=testheap.o heap.o testheap:$(Obj) $(CC) -o testheap $(Obj) $(Cflag) .c.o: $(CC) -c $< $(Cflag)