Added heap binomial adding.
parent
474953e5ec
commit
22c097789f
|
@ -0,0 +1,191 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct _node {
|
||||
struct _node* right;
|
||||
struct _node* child;
|
||||
long lvl;
|
||||
long key;
|
||||
} node;
|
||||
|
||||
typedef struct _list {
|
||||
node *node;
|
||||
struct _list *next;
|
||||
} list;
|
||||
|
||||
void visit_node_post_order(node *q, void (*callback)(node *)) {
|
||||
if (!q) {
|
||||
return;
|
||||
}
|
||||
|
||||
visit_node_post_order(q->child, callback);
|
||||
visit_node_post_order(q->right, callback);
|
||||
callback(q);
|
||||
}
|
||||
|
||||
void visit_node_pre_order(node *q, void (*callback)(node *)) {
|
||||
if (!q) {
|
||||
return;
|
||||
}
|
||||
|
||||
callback(q);
|
||||
visit_node_post_order(q->right, callback);
|
||||
visit_node_post_order(q->child, callback);
|
||||
}
|
||||
|
||||
|
||||
void node_destroy(list *q) {
|
||||
void (*func)(node *) = (void (*)(node *))free;
|
||||
list *t = q;
|
||||
while (t) {
|
||||
visit_node_post_order(t->node, func);
|
||||
t = t->next;
|
||||
}
|
||||
}
|
||||
|
||||
node* node_create(long key) {
|
||||
node *res = (node *)malloc(sizeof(node));
|
||||
res->lvl = 0;
|
||||
res->key = key;
|
||||
res->right = NULL;
|
||||
res->child = NULL;
|
||||
return res;
|
||||
}
|
||||
|
||||
node* node_union_same_lvl(node* l, node* r) {
|
||||
if (!l) {
|
||||
return r;
|
||||
}
|
||||
|
||||
if (!r) {
|
||||
return l;
|
||||
}
|
||||
|
||||
if (l->lvl != r->lvl) {
|
||||
fprintf(stderr, "L lvl %d and R lvl %d do mismatch. Returning NULL\n", l->lvl, r->lvl);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
node* item;
|
||||
node* subitem;
|
||||
|
||||
if (l->key > r->key) {
|
||||
// l main
|
||||
item = l;
|
||||
subitem = r;
|
||||
} else {
|
||||
// r main
|
||||
item = r;
|
||||
subitem = l;
|
||||
}
|
||||
|
||||
if (item->child) {
|
||||
node *t = item->child;
|
||||
while (t->right != NULL) {
|
||||
t = t->right;
|
||||
}
|
||||
t->right = subitem;
|
||||
} else {
|
||||
item->child = subitem;
|
||||
}
|
||||
item->lvl++; // we merged two same lvl binomial heap nodes and created on lvl bigger
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
void dump_node(node *q) {
|
||||
printf("%d ", q->key);
|
||||
}
|
||||
|
||||
void dump_heap(list *q) {
|
||||
list *t = q;
|
||||
while (t) {
|
||||
printf("Binom lvl %d\n", t->node->lvl);
|
||||
visit_node_pre_order(t->node, dump_node);
|
||||
printf("\n");
|
||||
t = t->next;
|
||||
}
|
||||
}
|
||||
|
||||
list* node_add(list *q, long key) {
|
||||
list *c = NULL;
|
||||
list *a = q;
|
||||
node *b = node_create(key);
|
||||
list *bl;
|
||||
|
||||
if (!q) {
|
||||
a = (list*)malloc(sizeof(list));
|
||||
a->node = b;
|
||||
return a;
|
||||
}
|
||||
|
||||
while (a) {
|
||||
if (a->node->lvl > b->lvl) { // it a always will be bigger or equal
|
||||
list *el = (list*)malloc(sizeof(list));
|
||||
el->node = b;
|
||||
el->next = a;
|
||||
return el;
|
||||
} else {
|
||||
c = a->next;
|
||||
a->node = node_union_same_lvl(a->node, b);
|
||||
bl = a;
|
||||
b = a->node;
|
||||
a = c;
|
||||
}
|
||||
}
|
||||
|
||||
return bl;
|
||||
|
||||
}
|
||||
|
||||
int node_del(node *q) {
|
||||
// TODO
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
const int MAX_BUFFER = 0x1000;
|
||||
|
||||
int main() {
|
||||
char cmd[MAX_BUFFER];
|
||||
list *q = NULL;
|
||||
while (1) {
|
||||
|
||||
fgets(cmd, MAX_BUFFER, stdin);
|
||||
printf("Got command %s\n", cmd);
|
||||
|
||||
if (strlen(cmd) == 0 || cmd[0] == '\n') {
|
||||
printf("Finished reading\n");
|
||||
break;
|
||||
} else if (memcmp(cmd, "ADD", 3) == 0) {
|
||||
// handle command add
|
||||
int x = atoi(cmd + 4);
|
||||
|
||||
q = node_add(q, x);
|
||||
|
||||
printf("Added number: %d\n", x);
|
||||
|
||||
} else if (memcmp(cmd, "DEL", 3) == 0) {
|
||||
// handle command del
|
||||
if (!q) {
|
||||
fprintf(stderr, "There is nothing to delete - heap is empty\n");
|
||||
continue;
|
||||
}
|
||||
// TODO: long key = node_del(q);
|
||||
// printf("Removed element: %d\n", key);
|
||||
} else {
|
||||
// handle unknown command
|
||||
fprintf(stderr, "Got unknown command %s\n", cmd);
|
||||
}
|
||||
|
||||
dump_heap(q);
|
||||
|
||||
}
|
||||
|
||||
if (!q) {
|
||||
node_destroy(q);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,157 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
typedef struct _node {
|
||||
struct _node* left;
|
||||
struct _node* right;
|
||||
struct _node* child;
|
||||
long lvl;
|
||||
long key;
|
||||
} node;
|
||||
|
||||
void visit_node_post_order(node *q, void (*callback)(node *)) {
|
||||
if (!q) {
|
||||
return;
|
||||
}
|
||||
|
||||
visit_node_post_order(q->child, callback);
|
||||
visit_node_post_order(q->right, callback);
|
||||
callback(q);
|
||||
}
|
||||
|
||||
void node_destroy(node *q) {
|
||||
void (*func)(node *) = (void (*)(node *))free;
|
||||
visit_node_post_order(q, func);
|
||||
}
|
||||
|
||||
node* node_create(long key) {
|
||||
node *res = (node *)malloc(sizeof(node));
|
||||
res->lvl = 0;
|
||||
res->key = key;
|
||||
res->left = res;
|
||||
res->right = res;
|
||||
res->child = NULL;
|
||||
return res;
|
||||
}
|
||||
|
||||
node* node_union_same_lvl(node* l, node* r) {
|
||||
if (!l) {
|
||||
return r;
|
||||
}
|
||||
|
||||
if (!r) {
|
||||
return l;
|
||||
}
|
||||
|
||||
if (l->lvl != r->lvl) {
|
||||
fprintf(stderr, "L lvl %d and R lvl %d do mismatch. Returning NULL\n", l->lvl, r->lvl);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
node* item;
|
||||
node* subitem;
|
||||
|
||||
if (l->key > r->key) {
|
||||
// l main
|
||||
item = l;
|
||||
subitem = r;
|
||||
} else {
|
||||
// r main
|
||||
item = r;
|
||||
subitem = l;
|
||||
}
|
||||
|
||||
if (item->child) {
|
||||
item->child->left->right = subitem; // we have two directional list (left,right links) where left of the beginning is the
|
||||
// end and right of the end is the beginning
|
||||
} else {
|
||||
item->child = subitem;
|
||||
}
|
||||
item->lvl++; // we merged two same lvl binomial heap nodes and created on lvl bigger
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
node* node_add(node *q, long key) {
|
||||
node *c = NULL;
|
||||
node *a = q;
|
||||
node *b = node_create(key);
|
||||
|
||||
if (q->lvl < 0) {
|
||||
return b;
|
||||
}
|
||||
|
||||
while (a) {
|
||||
if (a->lvl > b->lvl) { // it a always will be bigger or equal
|
||||
b->right = a;
|
||||
a->left->right = b;
|
||||
b->left = a->left; // a's ending
|
||||
a->left = b;
|
||||
return b;
|
||||
} else {
|
||||
b = node_union_same_lvl(a, b);
|
||||
c = a->right;
|
||||
a->right = NULL;
|
||||
|
||||
if (c == q) {
|
||||
break;
|
||||
}
|
||||
|
||||
a = c;
|
||||
}
|
||||
}
|
||||
|
||||
return b;
|
||||
|
||||
}
|
||||
|
||||
int node_del(node *q) {
|
||||
// TODO
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
const int MAX_BUFFER = 0x1000;
|
||||
|
||||
int main() {
|
||||
char cmd[MAX_BUFFER];
|
||||
node *q = (node *)malloc(sizeof(node));
|
||||
q->lvl = -1;
|
||||
q->key = 0xdeadbeaf; // it doesn't mother honestly
|
||||
while (1) {
|
||||
fgets(cmd, MAX_BUFFER, stdin);
|
||||
printf("Got command %s\n", cmd);
|
||||
|
||||
if (strlen(cmd) == 0 || cmd[0] == '\n') {
|
||||
printf("Finished reading\n");
|
||||
break;
|
||||
} else if (memcmp(cmd, "ADD", 3) == 0) {
|
||||
// handle command add
|
||||
int x = atoi(cmd + 4);
|
||||
|
||||
q = node_add(q, x);
|
||||
|
||||
printf("Added number: %d\n", x);
|
||||
|
||||
} else if (memcmp(cmd, "DEL", 3) == 0) {
|
||||
// handle command del
|
||||
if (!q) {
|
||||
fprintf(stderr, "There is nothing to delete - heap is empty\n");
|
||||
continue;
|
||||
}
|
||||
long key = node_del(q);
|
||||
printf("Removed element: %d\n", key);
|
||||
} else {
|
||||
// handle unknown command
|
||||
fprintf(stderr, "Got unknown command %s\n", cmd);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!q) {
|
||||
node_destroy(q);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue