|
| 1 | +#include <stdlib.h> |
| 2 | +#include <stdint.h> |
| 3 | +#include <stdio.h> |
| 4 | +#include <string.h> |
| 5 | +#include "heap.h" |
| 6 | + |
| 7 | +heap_ctrl_t * hp_create(size_t size) { |
| 8 | + heap_ctrl_t * h = (heap_ctrl_t *) calloc(1, sizeof(heap_ctrl_t)); |
| 9 | + h->array = (data_t **) calloc(size, sizeof(data_t *)); |
| 10 | + h->size = size; |
| 11 | + return h; |
| 12 | +} |
| 13 | + |
| 14 | +void hp_destroy(heap_ctrl_t ** heap) { |
| 15 | + if (*heap == (heap_ctrl_t *) NULL) |
| 16 | + return; |
| 17 | + |
| 18 | + memset((*heap)->array, 0x00, (*heap)->size * sizeof(data_t *)); |
| 19 | + free((*heap)->array); |
| 20 | + |
| 21 | + memset(*heap, 0x00, sizeof(heap_ctrl_t)); |
| 22 | + free(*heap); |
| 23 | + |
| 24 | + heap = NULL; |
| 25 | +} |
| 26 | + |
| 27 | +int32_t hp_insert(heap_ctrl_t * heap, int32_t data) { |
| 28 | + if (heap == (heap_ctrl_t *) NULL) |
| 29 | + return ERR_HEAP_NULL; |
| 30 | + |
| 31 | + if (heap->next == heap->size - 1) |
| 32 | + return ERR_HEAP_FULL; |
| 33 | + |
| 34 | + int32_t parent, leaf; |
| 35 | + data_t * datas = (data_t *) calloc(1, sizeof(data_t)); |
| 36 | + datas->data = data; |
| 37 | + |
| 38 | + heap->array[heap->next] = datas; |
| 39 | + parent = heap->next; |
| 40 | + leaf = heap->next; |
| 41 | + |
| 42 | + while (parent != 0) { |
| 43 | + if (parent % 2 == 0) |
| 44 | + parent = (parent - 2) / 2; |
| 45 | + else |
| 46 | + parent = (parent - 1) / 2; |
| 47 | + |
| 48 | + |
| 49 | + if (heap->array[parent]->data <= data) { |
| 50 | + heap->array[leaf] = heap->array[parent]; |
| 51 | + heap->array[parent] = datas; |
| 52 | + leaf = parent; |
| 53 | + } |
| 54 | + } |
| 55 | + ++heap->next; |
| 56 | + |
| 57 | + return SUCCESS; |
| 58 | +} |
| 59 | + |
| 60 | +int32_t hp_remove(heap_ctrl_t * heap) { |
| 61 | + if (heap == (heap_ctrl_t *) NULL) |
| 62 | + return ERR_HEAP_NULL; |
| 63 | + |
| 64 | + if (heap->next == 0) |
| 65 | + return ERR_HEAP_EMPTY; |
| 66 | + |
| 67 | + if (heap->array[0] != (data_t *) NULL) |
| 68 | + free(heap->array[0]); |
| 69 | + |
| 70 | + --heap->next; |
| 71 | + heap->array[0] = heap->array[heap->next]; |
| 72 | + heap->array[heap->next] = (data_t *) NULL; |
| 73 | + |
| 74 | + hp_heapfy(heap); |
| 75 | + |
| 76 | + return SUCCESS; |
| 77 | +} |
| 78 | + |
| 79 | +int32_t hp_heapfy(heap_ctrl_t * heap) { |
| 80 | + if (heap == (heap_ctrl_t *) NULL) |
| 81 | + return ERR_HEAP_NULL; |
| 82 | + |
| 83 | + size_t l, r; |
| 84 | + int32_t parent = 0; |
| 85 | + |
| 86 | + while (1) { |
| 87 | + l = LEFT(parent); |
| 88 | + r = RIGHT(parent); |
| 89 | + |
| 90 | + if (heap->array[r] == (data_t *) NULL) { |
| 91 | + if (heap->array[l] == (data_t *) NULL) |
| 92 | + break; |
| 93 | + if (heap->array[l]->data >= heap->array[parent]->data) { |
| 94 | + hp_swap(&(heap)->array[l], &(heap)->array[parent]); |
| 95 | + parent = l; |
| 96 | + } else { |
| 97 | + break; |
| 98 | + } |
| 99 | + } else { |
| 100 | + if ((heap->array[l]->data >= heap->array[parent]->data) && (heap->array[l]->data > heap->array[r]->data)) { |
| 101 | + hp_swap(&(heap)->array[l], &(heap)->array[parent]); |
| 102 | + parent = l; |
| 103 | + } else if ((heap->array[r]->data >= heap->array[parent]->data) && (heap->array[r]->data > heap->array[l]->data)) { |
| 104 | + hp_swap(&(heap)->array[r], &(heap)->array[parent]); |
| 105 | + parent = r; |
| 106 | + } else { |
| 107 | + break; |
| 108 | + } |
| 109 | + } |
| 110 | + } |
| 111 | + |
| 112 | + return SUCCESS; |
| 113 | +} |
| 114 | + |
| 115 | +void hp_swap(data_t ** a, data_t ** b) { |
| 116 | + data_t * tmp; |
| 117 | + tmp = *a; |
| 118 | + *a = *b; |
| 119 | + *b = tmp; |
| 120 | +} |
| 121 | + |
| 122 | +int32_t hp_sort(heap_ctrl_t * heap) { |
| 123 | + if (heap == (heap_ctrl_t *) NULL) |
| 124 | + return ERR_HEAP_NULL; |
| 125 | + |
| 126 | + data_t ** sorted = (data_t **) calloc(heap->size, sizeof(data_t *)); |
| 127 | + |
| 128 | + int32_t i; |
| 129 | + |
| 130 | + for (i = (heap->next - 1); i >= 0; --i) { |
| 131 | + sorted[i] = heap->array[0]; |
| 132 | + heap->array[0] = heap->array[i]; |
| 133 | + heap->array[i] = (data_t *) NULL; |
| 134 | + |
| 135 | + hp_heapfy(heap); |
| 136 | + } |
| 137 | + |
| 138 | + for (i = 0; i < (int32_t) heap->next; ++i) |
| 139 | + heap->array[i] = sorted[i]; |
| 140 | + |
| 141 | + memset(sorted, 0x00, heap->size * sizeof(data_t *)); |
| 142 | + free(sorted); |
| 143 | + |
| 144 | + return SUCCESS; |
| 145 | +} |
| 146 | + |
| 147 | +int32_t hp_get_head(heap_ctrl_t * heap) { |
| 148 | + if (heap == (heap_ctrl_t *) NULL) |
| 149 | + return ERR_HEAP_NULL; |
| 150 | + if (heap->next == 0) |
| 151 | + return ERR_HEAP_EMPTY; |
| 152 | + |
| 153 | + return heap->array[0]->data; |
| 154 | +} |
| 155 | + |
| 156 | +void hp_print(heap_ctrl_t * heap) { |
| 157 | + if (heap == (heap_ctrl_t *) NULL) |
| 158 | + return; |
| 159 | + |
| 160 | + size_t i; |
| 161 | + |
| 162 | + printf("["); |
| 163 | + for (i = 0; i < heap->next + 1; ++i) { |
| 164 | + if (heap->array[i] != (data_t *) NULL) |
| 165 | + printf("%d ", heap->array[i]->data); |
| 166 | + } |
| 167 | + printf("]\n"); |
| 168 | +} |
0 commit comments