Created
September 7, 2009 23:10
-
-
Save tyler/182611 to your computer and use it in GitHub Desktop.
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
#include <stdio.h> | |
#include <stdlib.h> | |
#include <unistd.h> | |
#include <sys/types.h> | |
#include <sys/mman.h> | |
#include <sys/fcntl.h> | |
#include <time.h> | |
typedef struct _Node { | |
int key; | |
int value; | |
} Node; | |
typedef struct _BinaryHeap { | |
Node * root; | |
char * data; | |
int next; | |
int size; | |
int fd; | |
} BinaryHeap; | |
void set_size(BinaryHeap * heap, int size) { | |
int * data_as_ints = (int *) heap->data; | |
data_as_ints[1] = size; | |
} | |
void set_next(BinaryHeap * heap, int next) { | |
int * data_as_ints = (int *) heap->data; | |
data_as_ints[0] = next; | |
} | |
BinaryHeap * binary_heap_new(const char * filename) { | |
int initial_size = 4096; | |
BinaryHeap * heap = (BinaryHeap *) malloc(sizeof(BinaryHeap)); | |
heap->fd = open(filename, O_RDWR | O_CREAT | O_TRUNC); | |
lseek(heap->fd, initial_size - 1, SEEK_SET); | |
write(heap->fd, "", 1); | |
heap->data = mmap((caddr_t) 0, initial_size, PROT_READ | PROT_WRITE, MAP_SHARED, heap->fd, 0); | |
heap->root = (Node *) (sizeof(int) * 2 + heap->data); | |
heap->size = initial_size; | |
heap->next = 0; | |
return heap; | |
} | |
BinaryHeap * binary_heap_open(const char * filename) { | |
BinaryHeap * heap = (BinaryHeap *) malloc(sizeof(BinaryHeap)); | |
heap->fd = open(filename, O_RDWR | O_CREAT); | |
heap->data = mmap((caddr_t) 0, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, heap->fd, 0); | |
heap->root = (Node *) (sizeof(int) * 2 + heap->data); | |
int * data_as_ints = (int *) heap->data; | |
heap->next = data_as_ints[0]; | |
heap->size = data_as_ints[1]; | |
return heap; | |
} | |
BinaryHeap * binary_heap_close(BinaryHeap * heap) { | |
set_size(heap, heap->size); | |
set_next(heap, heap->next); | |
munmap(heap->root, heap->size); | |
close(heap->fd); | |
} | |
Node * binary_heap_peek(BinaryHeap * heap) { | |
return heap->root; | |
} | |
BinaryHeap * binary_heap_insert(BinaryHeap * heap, int key, int value) { | |
Node * node = heap->root + heap->next; | |
node->key = key; | |
node->value = value; | |
int current = heap->next; | |
int parent = (current - 1) / 2; | |
while(parent >= 0 && heap->root[current].key < heap->root[parent].key) { | |
Node temp = heap->root[current]; | |
heap->root[current] = heap->root[parent]; | |
heap->root[parent] = temp; | |
current = parent; | |
parent = (current - 1) / 2; | |
} | |
heap->next++; | |
return heap; | |
} | |
Node binary_heap_delete(BinaryHeap * heap) { | |
if(heap->next == 0) { | |
Node blank_node; | |
blank_node.key = -1; | |
blank_node.value = -1; | |
return blank_node; | |
} | |
Node root_node = heap->root[0]; | |
heap->next--; | |
heap->root[0] = heap->root[heap->next]; | |
int current = 0; | |
int left = 1; | |
int right = 2; | |
while(1) { | |
if(left <= heap->next && heap->root[current].key > heap->root[left].key && | |
(right > heap->next || heap->root[left].key < heap->root[right].key)) { | |
Node temp = heap->root[current]; | |
heap->root[current] = heap->root[left]; | |
heap->root[left] = temp; | |
current = left; | |
} else if(right <= heap->next && heap->root[current].key > heap->root[right].key) { | |
Node temp = heap->root[current]; | |
heap->root[current] = heap->root[right]; | |
heap->root[right] = temp; | |
current = right; | |
} else { | |
break; | |
} | |
left = current * 2 + 1; | |
right = current * 2 + 2; | |
} | |
return root_node; | |
} | |
int main() { | |
srand(time(NULL)); | |
BinaryHeap * heap = binary_heap_new("heap.data"); | |
binary_heap_close(heap); | |
int i; | |
for(i = 0; i < 10; i++) { | |
heap = binary_heap_open("heap.data"); | |
int j; | |
for(j = 0; j < 4; j++) { | |
binary_heap_insert(heap, ((unsigned)rand() % 10), 1); | |
} | |
binary_heap_close(heap); | |
} | |
heap = binary_heap_open("heap.data"); | |
Node node; | |
while((node = binary_heap_delete(heap)).key != -1) { | |
printf("Dequeue: %d\n", node.key); | |
} | |
binary_heap_close(heap); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment