-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
0a54548
commit b46eb43
Showing
5 changed files
with
215 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
#include <assert.h> | ||
#include <stdint.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <unistd.h> | ||
|
||
#include "heap.h" | ||
|
||
bool u32_leq(void *a, void *b) { | ||
return *(uint32_t*)a < *(uint32_t*)b; | ||
} | ||
|
||
void u32_cpy(void *a, void *b) { | ||
*(uint32_t*)a = *(uint32_t*)b; | ||
} | ||
|
||
void test_heap_test_1(void) { | ||
fprintf(stderr, "WUT?\n"); | ||
|
||
char heap_mem[512]; | ||
struct heap *h = heap_create( heap_mem | ||
, sizeof(heap_mem) | ||
, sizeof(uint32_t) | ||
, u32_leq | ||
, u32_cpy ); | ||
|
||
fprintf(stderr, "heap_size: %ld\n", heap_size(h)); | ||
fprintf(stdout, "# heap_empty: %s\n", heap_empty(h) ? "yes" : "no"); | ||
|
||
uint32_t vs[] = {5,18,6,4,28,3,2,1}; | ||
size_t i = 0; | ||
for(; i < sizeof(vs)/sizeof(vs[0]); i++ ) { | ||
if( !heap_add(h, &vs[i]) ) { | ||
break; | ||
} | ||
} | ||
|
||
#define o(i) (i)*sizeof(uint32_t) | ||
|
||
size_t j = 0; | ||
fprintf(stdout, "digraph G {\n"); | ||
for(i = 0; i < h->n; i++, j += sizeof(uint32_t) ) { | ||
if( i ) { | ||
size_t p = i ? (i-1)/2 : 0; | ||
fprintf(stdout, "%d -> %d;\n" | ||
, *(uint32_t*)&h->data[o(p)] | ||
, *(uint32_t*)&h->data[o(i)] | ||
); | ||
} | ||
} | ||
fprintf(stdout, "}\n"); | ||
|
||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
#ifndef __heap_h | ||
#define __heap_h | ||
|
||
#include <stddef.h> | ||
#include <stdbool.h> | ||
|
||
struct heap; | ||
|
||
struct heap { | ||
size_t n; | ||
size_t size; | ||
size_t item_size; | ||
bool (*leq)(void*,void*); | ||
void (*cpy)(void*,void*); | ||
char data[0]; | ||
}; | ||
|
||
|
||
// FIXED SIZE BINARY HEAP | ||
|
||
struct heap * heap_create( void *mem | ||
, size_t memsize | ||
, size_t item_size | ||
, bool (*item_leq)(void*,void*) | ||
, void (*item_cpy)(void*,void*) | ||
); | ||
|
||
bool heap_empty(struct heap*); | ||
size_t heap_size(struct heap*); | ||
bool heap_add(struct heap *, void *); | ||
void *heap_get(struct heap*); | ||
void heap_del(struct heap*); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
#include <string.h> | ||
#include <stdint.h> | ||
#include "heap.h" | ||
|
||
/*struct heap {*/ | ||
/* size_t n;*/ | ||
/* size_t size;*/ | ||
/* size_t item_size;*/ | ||
/* bool (*leq)(void*,void*);*/ | ||
/* void (*cpy)(void*,void*);*/ | ||
/* char data[0];*/ | ||
/*};*/ | ||
|
||
struct heap *heap_create( void *mem | ||
, size_t memsize | ||
, size_t item_size | ||
, bool (*item_leq)(void*,void*) | ||
, void (*item_cpy)(void*,void*) | ||
) { | ||
|
||
const size_t headsz = sizeof(struct heap); | ||
const size_t minsz = 3*item_size + headsz; | ||
|
||
if( memsize < minsz ) { | ||
return 0; | ||
} | ||
|
||
struct heap *h = mem; | ||
h->n = 0; | ||
h->size = (memsize - headsz) / item_size; | ||
h->item_size = item_size; | ||
h->leq = item_leq; | ||
h->cpy = item_cpy; | ||
|
||
return h; | ||
} | ||
|
||
static inline size_t L(size_t i) { | ||
return (i*2 + 1); | ||
} | ||
|
||
static inline size_t R(size_t i) { | ||
return (i*2 + 2); | ||
} | ||
|
||
static inline size_t P(size_t i) { | ||
return (i-1)/2; | ||
} | ||
|
||
static inline void* pitem(struct heap *h, size_t i) { | ||
return &h->data[i*h->item_size]; | ||
} | ||
|
||
static inline void swap(struct heap *h, size_t i, size_t j) { | ||
char tmp[h->item_size]; | ||
|
||
void *pi = pitem(h, i); | ||
void *pj = pitem(h, j); | ||
|
||
h->cpy(tmp, pi); | ||
h->cpy(pi, pj); | ||
h->cpy(pj, tmp); | ||
} | ||
|
||
static inline bool leq(struct heap *h, size_t i, size_t j) { | ||
return h->leq(pitem(h,i), pitem(h,j)); | ||
} | ||
|
||
static void sift_down(struct heap *h, size_t i) { | ||
while( L(i) < h->n ) { | ||
size_t l = L(i); | ||
size_t r = R(i); | ||
size_t j = l; | ||
if( r < h->n && leq(h, r, l) ) { | ||
j = r; | ||
} | ||
if( leq(h, i, j) ) { | ||
break; | ||
} | ||
swap(h, i, j); | ||
i = j; | ||
} | ||
} | ||
|
||
static void sift_up(struct heap *h, size_t i) { | ||
while( i && leq(h, i, P(i)) ) { | ||
swap(h, i, P(i)); | ||
i = P(i); | ||
} | ||
} | ||
|
||
size_t heap_size(struct heap *h) { | ||
return h->size; | ||
} | ||
|
||
bool heap_empty(struct heap *h) { | ||
return (0 == h->n); | ||
} | ||
|
||
bool heap_add(struct heap *h, void *v) { | ||
if( h->n >= h->size ) { | ||
return false; | ||
} | ||
|
||
size_t i = h->n++; | ||
|
||
h->cpy(pitem(h,i), v); | ||
|
||
sift_up(h, i); | ||
return true; | ||
} | ||
|
||
void *heap_get(struct heap *h) { | ||
return 0; | ||
} | ||
|
||
void heap_pop(struct heap *h) { | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters