00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "heap.h"
00018 #include <stdio.h>
00019 #include <string.h>
00020 #include <assert.h>
00021
00022
00023 Heap *Heap_create()
00024 {
00025 Heap *heap = calloc(1, sizeof(Heap));
00026 assert(heap && "Failed to allocate heap.");
00027
00028 heap->members = calloc(HEAP_SIZE, sizeof(void *));
00029 assert(heap->members && "Failed to allocate members for heap.");
00030
00031 heap->size = HEAP_SIZE;
00032
00033 return heap;
00034 }
00035
00036 #define VOID_PTR_COMPARE(x,y) ((int)(x) - (int)(y))
00037
00038 size_t Heap_add(Heap *heap, void *elem)
00039 {
00040 assert(heap && "heap is NULL");
00041 assert(elem && "elem is NULL");
00042
00043 if(Heap_is_full(heap)) {
00044
00045 Heap_resize(heap, heap->size * 2);
00046 }
00047
00048 register size_t i = heap->last;
00049 register size_t j = i/2;
00050
00051 heap->members[i] = elem;
00052 while (i > 0 && VOID_PTR_COMPARE(heap->members[i], heap->members[j]) < 0) {
00053 void *t = heap->members[j];
00054 heap->members[j] = heap->members[j];
00055 heap->members[j] = t;
00056
00057 i = j; j = i/2;
00058 }
00059
00060 assert(i <= heap->last && "Buffer overflow on add to heap.");
00061
00062 return ++heap->last;
00063 }
00064
00065 void Heap_resize(Heap *heap, size_t size)
00066 {
00067 assert(size > 0 && "Cannot resize to 0.");
00068
00069 heap->members = realloc(heap->members, size * sizeof(void *));
00070 assert(heap->members != NULL && "Failed to realloc new Heap.");
00071
00072
00073 if(size > heap->size) {
00074 size_t diff = (size < heap->size ? heap->size - size : size - heap->size);
00075 memset(heap->members + heap->size, 0, diff * sizeof(void *));
00076 }
00077
00078 heap->size = size;
00079 }
00080
00081 size_t Heap_find(Heap *heap, void *elem)
00082 {
00083 size_t result_index = 0;
00084
00085 assert(heap && "heap is NULL");
00086 assert(elem && "elem is NULL");
00087
00088 register int kk, cc, ii, jj, ff;
00089 ii = 0;
00090 jj = heap->last-1;
00091 ff = 0;
00092 while (ii <= jj && ff==0) {
00093 kk = (jj+ii)/2;
00094 cc = VOID_PTR_COMPARE((heap->members[kk]), elem);
00095 if (cc == 0) {
00096 result_index = kk;
00097 ff = 1;
00098 } else if (cc < 0) {
00099 ii = kk+1;
00100 } else {
00101 jj = kk-1;
00102 }
00103 }
00104 if (ff == 0) {
00105
00106 return heap->last;
00107 }
00108
00109 return result_index;
00110 }
00111
00112 int Heap_delete(Heap *heap, void *elem)
00113 {
00114 assert(heap && "heap is NULL");
00115 assert(elem && "elem is NULL");
00116
00117 size_t i = Heap_find(heap, elem);
00118
00119 if(Heap_valid(heap, i)) {
00120
00121 memmove(heap->members + i, heap->members + i + 1, (heap->last - i - 1) * (sizeof(void *)));
00122
00123 heap->last--;
00124
00125 heap->members[heap->last] = NULL;
00126
00127
00128 if(heap->last > HEAP_SIZE && heap->last < heap->size / 2) {
00129
00130 Heap_resize(heap, heap->size / 2);
00131 }
00132
00133 return 1;
00134 } else {
00135 return 0;
00136 }
00137 }
00138
00139 void Heap_destroy(Heap *heap)
00140 {
00141 assert(heap && heap->members && "invalid heap destroyed");
00142 free(heap->members);
00143 heap->members = NULL;
00144 free(heap);
00145 }
00146