Add pset3, took 15 + 32 = 47 mins
This commit is contained in:
parent
bd09ef96dc
commit
e23ed8daa6
189
semester3/pset3/7-2-Binomial-Queue-TakeTwo.c
Normal file
189
semester3/pset3/7-2-Binomial-Queue-TakeTwo.c
Normal file
|
@ -0,0 +1,189 @@
|
||||||
|
// 15:10 - 15:42 - 32min
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#define MAX 100
|
||||||
|
|
||||||
|
typedef struct node {
|
||||||
|
int val, degree;
|
||||||
|
struct node *child, *sibling;
|
||||||
|
} node;
|
||||||
|
|
||||||
|
typedef struct list {
|
||||||
|
node **arr;
|
||||||
|
int size;
|
||||||
|
} list;
|
||||||
|
|
||||||
|
node *newNode(int val) {
|
||||||
|
node *n = malloc(sizeof(node));
|
||||||
|
n->val = val;
|
||||||
|
n->degree = 0;
|
||||||
|
n->child = NULL;
|
||||||
|
n->sibling = NULL;
|
||||||
|
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
list *newList(int capacity) {
|
||||||
|
list *li = malloc(sizeof(list));
|
||||||
|
|
||||||
|
li->arr = malloc(sizeof(node *) * capacity);
|
||||||
|
li->size = 0;
|
||||||
|
|
||||||
|
return li;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pushBack(list *li, node *n) { li->arr[li->size++] = n; }
|
||||||
|
|
||||||
|
list *erase(list *li, int loc) {
|
||||||
|
for (int i = loc, size = li->size; i < size - 1; i++) {
|
||||||
|
li->arr[i] = li->arr[i + 1];
|
||||||
|
}
|
||||||
|
li->size--;
|
||||||
|
return li;
|
||||||
|
}
|
||||||
|
|
||||||
|
list *unionList(list *l, list *r) {
|
||||||
|
int i = 0, j = 0;
|
||||||
|
list *li = newList(MAX);
|
||||||
|
|
||||||
|
while (i < l->size && j < r->size) {
|
||||||
|
if (l->arr[i]->degree < r->arr[j]->degree) {
|
||||||
|
pushBack(li, l->arr[i++]);
|
||||||
|
} else {
|
||||||
|
pushBack(li, r->arr[j++]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (i < l->size) {
|
||||||
|
pushBack(li, l->arr[i++]);
|
||||||
|
}
|
||||||
|
while (j < r->size) {
|
||||||
|
pushBack(li, r->arr[j++]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return li;
|
||||||
|
}
|
||||||
|
|
||||||
|
void swapNode(node *l, node *r) {
|
||||||
|
node tmp = *l;
|
||||||
|
*l = *r;
|
||||||
|
*r = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
node *merge(node *l, node *r) {
|
||||||
|
// remember, smaller one goes up
|
||||||
|
if (l->val > r->val) {
|
||||||
|
swapNode(l, r);
|
||||||
|
}
|
||||||
|
r->sibling = l->child;
|
||||||
|
l->child = r;
|
||||||
|
|
||||||
|
l->degree++;
|
||||||
|
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
list *adjust(list *li) {
|
||||||
|
if (li->size == 1) {
|
||||||
|
return li;
|
||||||
|
}
|
||||||
|
int i = 0, j = 0, k = 0;
|
||||||
|
if (li->size == 2) {
|
||||||
|
j = 1;
|
||||||
|
k = li->size;
|
||||||
|
} else {
|
||||||
|
j = 1;
|
||||||
|
k = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (i < li->size) {
|
||||||
|
if (j == li->size) {
|
||||||
|
i++;
|
||||||
|
} else if (li->arr[i]->degree < li->arr[j]->degree) {
|
||||||
|
i++;
|
||||||
|
j++;
|
||||||
|
if (k < li->size) {
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
} else if (k < li->size && li->arr[i]->degree == li->arr[j]->degree &&
|
||||||
|
li->arr[i]->degree == li->arr[k]->degree) {
|
||||||
|
i++;
|
||||||
|
j++;
|
||||||
|
k++;
|
||||||
|
} else if (li->arr[i]->degree == li->arr[j]->degree) {
|
||||||
|
li->arr[i] = merge(li->arr[i], li->arr[j]);
|
||||||
|
erase(li, j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return li;
|
||||||
|
}
|
||||||
|
|
||||||
|
list *insert(list *li, int val) {
|
||||||
|
node *n = newNode(val);
|
||||||
|
list *tmp = newList(MAX);
|
||||||
|
pushBack(tmp, n);
|
||||||
|
|
||||||
|
tmp = unionList(li, tmp);
|
||||||
|
return adjust(tmp);
|
||||||
|
}
|
||||||
|
|
||||||
|
int getDigits(int i) {
|
||||||
|
int count = 0;
|
||||||
|
while (i) {
|
||||||
|
i /= 10;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void printLevel(node *n, int level) {
|
||||||
|
if (n) {
|
||||||
|
printLevel(n->sibling, level);
|
||||||
|
if (level == 1) {
|
||||||
|
printf("%d,", n->val);
|
||||||
|
} else {
|
||||||
|
printLevel(n->child, level - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void printHeap(node *n) {
|
||||||
|
int level = 0;
|
||||||
|
for (node *ptr = n; ptr != NULL; ptr = ptr->child) {
|
||||||
|
printLevel(n, ++level);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void printTree(list *li, int k) {
|
||||||
|
int present = 0;
|
||||||
|
for (int i = 0, size = li->size; i < size; i++) {
|
||||||
|
if (li->arr[i]->degree == k) {
|
||||||
|
printHeap(li->arr[i]);
|
||||||
|
present = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!present) {
|
||||||
|
printf("0,\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
char buf[MAX];
|
||||||
|
fgets(buf, MAX, stdin);
|
||||||
|
list *li = newList(MAX);
|
||||||
|
|
||||||
|
int tmp;
|
||||||
|
int offset = 0;
|
||||||
|
while (sscanf(buf + offset, "%d,", &tmp) != EOF) {
|
||||||
|
li = insert(li, tmp); // remember li =
|
||||||
|
offset += getDigits(tmp) + 1; // remember to + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
int k;
|
||||||
|
scanf("%d", &k);
|
||||||
|
printTree(li, k);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -79,6 +79,7 @@ Node *merge(Node *l, Node *r) {
|
||||||
swapNode(l, r);
|
swapNode(l, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// sub-node might have a sibling, but head node doesn't have one.
|
||||||
r->parent = l;
|
r->parent = l;
|
||||||
r->sibling = l->child;
|
r->sibling = l->child;
|
||||||
|
|
||||||
|
@ -105,7 +106,7 @@ list *adjust(list *l) {
|
||||||
|
|
||||||
// can't use i != size here, since the list will shrink.
|
// can't use i != size here, since the list will shrink.
|
||||||
while (i < l->size) {
|
while (i < l->size) {
|
||||||
// only one element remains
|
// only one element remains, if j > size, then i == size
|
||||||
if (j == l->size) {
|
if (j == l->size) {
|
||||||
i++;
|
i++;
|
||||||
} else if (l->arr[i]->degree < l->arr[j]->degree) {
|
} else if (l->arr[i]->degree < l->arr[j]->degree) {
|
||||||
|
@ -116,15 +117,14 @@ list *adjust(list *l) {
|
||||||
}
|
}
|
||||||
} else if (k < l->size && l->arr[i]->degree == l->arr[j]->degree &&
|
} else if (k < l->size && l->arr[i]->degree == l->arr[j]->degree &&
|
||||||
l->arr[i]->degree == l->arr[k]->degree) {
|
l->arr[i]->degree == l->arr[k]->degree) {
|
||||||
|
// at most 3 same degrees, because of binary operations
|
||||||
i++;
|
i++;
|
||||||
j++;
|
j++;
|
||||||
k++;
|
k++;
|
||||||
} else if (l->arr[i]->degree == l->arr[j]->degree) {
|
} else if (l->arr[i]->degree == l->arr[j]->degree) {
|
||||||
l->arr[i] = merge(l->arr[i], l->arr[j]);
|
l->arr[i] = merge(l->arr[i], l->arr[j]);
|
||||||
erase(l, j);
|
erase(l, j);
|
||||||
if (k < l->size) {
|
// doesn't have to move k
|
||||||
k++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue