Add small C program
This commit is contained in:
parent
3309ca4a0c
commit
ac9353cef3
@ -13,3 +13,9 @@ steps:
|
|||||||
image: python
|
image: python
|
||||||
commands:
|
commands:
|
||||||
- python3 -c "print(6 * 7)"
|
- python3 -c "print(6 * 7)"
|
||||||
|
- name: gcc
|
||||||
|
image: gcc
|
||||||
|
commands:
|
||||||
|
- cd pairingheap
|
||||||
|
- gcc -o pairingheap pairingheap.c
|
||||||
|
- ./pairingheap
|
||||||
|
182
algo2/pairingheap.c
Normal file
182
algo2/pairingheap.c
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
#include <assert.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
struct PHeapNode {
|
||||||
|
int key;
|
||||||
|
struct PHeapNode *parent;
|
||||||
|
struct PHeapNode *left;
|
||||||
|
struct PHeapNode *right;
|
||||||
|
struct PHeapNode *children;
|
||||||
|
};
|
||||||
|
|
||||||
|
void phn_init(struct PHeapNode *phn, int key) {
|
||||||
|
phn->key = key;
|
||||||
|
phn->parent = NULL;
|
||||||
|
phn->left = NULL;
|
||||||
|
phn->right = NULL;
|
||||||
|
phn->children = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void phn_list_insert(struct PHeapNode **phn, struct PHeapNode *h) {
|
||||||
|
if (*phn == NULL) {
|
||||||
|
// list empty ==> h is only element now
|
||||||
|
h->left = h;
|
||||||
|
h->right = h;
|
||||||
|
*phn = h;
|
||||||
|
} else {
|
||||||
|
// list not empty ==> insert at the end
|
||||||
|
(*phn)->left->right = h;
|
||||||
|
h->left = (*phn)->left;
|
||||||
|
h->right = *phn;
|
||||||
|
(*phn)->left = h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void phn_list_remove(struct PHeapNode **phn, struct PHeapNode *h) {
|
||||||
|
assert(*phn != NULL);
|
||||||
|
|
||||||
|
if (h->left == h) {
|
||||||
|
assert(h->right == h);
|
||||||
|
// empty list
|
||||||
|
*phn = NULL;
|
||||||
|
} else {
|
||||||
|
// rearrange pointers
|
||||||
|
struct PHeapNode *tmp = h->left;
|
||||||
|
h->left->right = h->right;
|
||||||
|
h->right->left = tmp;
|
||||||
|
|
||||||
|
if (*phn == h) {
|
||||||
|
*phn = h->left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h->parent = NULL;
|
||||||
|
h->left = NULL;
|
||||||
|
h->right = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns a or b
|
||||||
|
struct PHeapNode *phn_union(struct PHeapNode *a, struct PHeapNode *b) {
|
||||||
|
struct PHeapNode *min = a->key < b->key ? a : b;
|
||||||
|
struct PHeapNode *max = a->key < b->key ? b : a;
|
||||||
|
|
||||||
|
phn_list_insert(&min->children, max);
|
||||||
|
return min;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PHeap {
|
||||||
|
struct PHeapNode *roots;
|
||||||
|
struct PHeapNode *min;
|
||||||
|
};
|
||||||
|
|
||||||
|
void ph_init(struct PHeap *ph) {
|
||||||
|
ph->roots = NULL;
|
||||||
|
ph->min = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ph_print(struct PHeap *ph) {
|
||||||
|
printf("roots: ");
|
||||||
|
if (ph->roots != NULL) {
|
||||||
|
struct PHeapNode *first = ph->roots;
|
||||||
|
struct PHeapNode *curr = first;
|
||||||
|
do {
|
||||||
|
printf("--{%d}", curr->key);
|
||||||
|
if (ph->min == curr) {
|
||||||
|
printf("'");
|
||||||
|
}
|
||||||
|
curr = curr->right;
|
||||||
|
} while (curr != first);
|
||||||
|
}
|
||||||
|
printf("--\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void ph_newtree(struct PHeap *ph, struct PHeapNode *h) {
|
||||||
|
assert(h->parent == NULL);
|
||||||
|
|
||||||
|
phn_list_insert(&ph->roots, h);
|
||||||
|
if (ph->min == NULL || h->key < ph->min->key) {
|
||||||
|
ph->min = h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ph_insert_malloc(struct PHeap *ph, int key) {
|
||||||
|
struct PHeapNode *h = malloc(sizeof(struct PHeapNode));
|
||||||
|
phn_init(h, key);
|
||||||
|
ph_newtree(ph, h);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PHeapNode *ph_deletemin(struct PHeap *ph) {
|
||||||
|
if (ph->min == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PHeapNode *m = ph->min;
|
||||||
|
|
||||||
|
// forest := forest \ {m}
|
||||||
|
phn_list_remove(&ph->roots, m);
|
||||||
|
ph->min = NULL;
|
||||||
|
|
||||||
|
// foreach child h of m do newTree(h)
|
||||||
|
while (m->children != NULL) {
|
||||||
|
struct PHeapNode *curr = m->children;
|
||||||
|
phn_list_remove(&m->children, m->children);
|
||||||
|
ph_newtree(ph, curr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// perform pair-wise union operations on the roots in forest
|
||||||
|
// update minPtr
|
||||||
|
if (ph->roots != NULL) {
|
||||||
|
struct PHeapNode *new_roots = NULL;
|
||||||
|
|
||||||
|
while (ph->roots != NULL && ph->roots->right != ph->roots) {
|
||||||
|
// while two elements are available:
|
||||||
|
struct PHeapNode *a = ph->roots;
|
||||||
|
struct PHeapNode *b = ph->roots->right;
|
||||||
|
phn_list_remove(&ph->roots, a);
|
||||||
|
phn_list_remove(&ph->roots, b);
|
||||||
|
|
||||||
|
a = phn_union(a, b);
|
||||||
|
phn_list_insert(&new_roots, a);
|
||||||
|
if (ph->min == NULL || a->key < ph->min->key) {
|
||||||
|
ph->min = a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ph->roots != NULL) {
|
||||||
|
// another element remains
|
||||||
|
struct PHeapNode *last = ph->roots;
|
||||||
|
phn_list_remove(&ph->roots, last);
|
||||||
|
phn_list_insert(&new_roots, last);
|
||||||
|
if (ph->min == NULL || last->key < ph->min->key) {
|
||||||
|
ph->min = last;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(ph->roots == NULL);
|
||||||
|
ph->roots = new_roots;
|
||||||
|
}
|
||||||
|
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
struct PHeap ph;
|
||||||
|
ph_init(&ph);
|
||||||
|
|
||||||
|
ph_insert_malloc(&ph, 42);
|
||||||
|
ph_insert_malloc(&ph, 10);
|
||||||
|
ph_insert_malloc(&ph, 0);
|
||||||
|
ph_insert_malloc(&ph, 100);
|
||||||
|
ph_insert_malloc(&ph, 12);
|
||||||
|
|
||||||
|
ph_print(&ph);
|
||||||
|
|
||||||
|
while (ph.min != NULL) {
|
||||||
|
struct PHeapNode *h = ph_deletemin(&ph);
|
||||||
|
printf("deleteMin: %d\n", h->key);
|
||||||
|
free(h);
|
||||||
|
}
|
||||||
|
|
||||||
|
ph_print(&ph);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user