From bd09ef96dc676216f59b6a504c1209d42994e925 Mon Sep 17 00:00:00 2001 From: juan Date: Tue, 25 Oct 2022 19:43:48 +0800 Subject: [PATCH] Add pset3 --- semester3/pset3/7-1-Binary-Heap.c | 37 ++--- semester3/pset3/7-2-Binomial-Queue.c | 212 +++++++++++++++++++++++++++ 2 files changed, 227 insertions(+), 22 deletions(-) create mode 100644 semester3/pset3/7-2-Binomial-Queue.c diff --git a/semester3/pset3/7-1-Binary-Heap.c b/semester3/pset3/7-1-Binary-Heap.c index bd47f08..a6adaea 100644 --- a/semester3/pset3/7-1-Binary-Heap.c +++ b/semester3/pset3/7-1-Binary-Heap.c @@ -2,13 +2,13 @@ #include typedef struct heap { - int* arr; + int *arr; int capacity; int size; } heap; -heap* newHeap(int size) { - heap* new = malloc(sizeof(heap)); +heap *newHeap(int size) { + heap *new = malloc(sizeof(heap)); new->arr = malloc(sizeof(int) * size); @@ -18,29 +18,21 @@ heap* newHeap(int size) { return new; } -void swap(int* l, int* r) { +void swap(int *l, int *r) { int tmp = *r; *r = *l; *l = tmp; } -int max(int l, int r) { - return (l > r) ? l : r; -} +int max(int l, int r) { return (l > r) ? l : r; } -int parent(int i) { - return (i - 1) / 2; -} +int parent(int i) { return (i - 1) / 2; } -int left (int i) { - return i * 2 + 1; -} +int left(int i) { return i * 2 + 1; } -int right (int i) { - return i * 2 + 2; -} +int right(int i) { return i * 2 + 2; } -void insert(heap* h, int val) { +void insert(heap *h, int val) { int i = h->size++; h->arr[i] = val; @@ -51,7 +43,7 @@ void insert(heap* h, int val) { } } -void heapify(heap * h, int i) { +void heapify(heap *h, int i) { int smallest = i; int l = left(i); int r = right(i); @@ -70,7 +62,7 @@ void heapify(heap * h, int i) { } } -void buildHeap(heap* h) { +void buildHeap(heap *h) { int start = h->size / 2 - 1; while (start >= 0) { @@ -78,7 +70,7 @@ void buildHeap(heap* h) { } } -void print(int* array, int size) { +void print(int *array, int size) { for (int i = 0; i < size - 1; i++) { printf("%d,", array[i]); } @@ -90,8 +82,9 @@ int main(void) { scanf("%d", &size); int tmp; - heap* h1 = newHeap(size); - heap* h2 = newHeap(size); + heap *h1 = newHeap(size); + heap *h2 = newHeap(size); + // make sure this one. h2->size = size; for (int i = 0; i < size; i++) { diff --git a/semester3/pset3/7-2-Binomial-Queue.c b/semester3/pset3/7-2-Binomial-Queue.c new file mode 100644 index 0000000..e4f5b2a --- /dev/null +++ b/semester3/pset3/7-2-Binomial-Queue.c @@ -0,0 +1,212 @@ +#include +#include +#define MAX 100 + +typedef struct Node { + int data, degree; + struct Node *child, *sibling, *parent; +} Node; + +typedef struct list { + int size; + Node **arr; +} list; + +list *newList() { + list *new = malloc(sizeof(list)); + new->size = 0; + new->arr = malloc(sizeof(Node *) * MAX); + return new; +} + +void pushBack(list *l, Node *new) { l->arr[l->size++] = new; } + +void erase(list *l, int loc) { + for (int i = loc; i < l->size - 1; i++) { + l->arr[i] = l->arr[i + 1]; + } + // remember this: + l->size--; +} + +void swapNode(Node *l, Node *r) { + Node *tmp = malloc(sizeof(Node)); + *tmp = *l; + *l = *r; + *r = *tmp; +} + +Node *newNode(int val) { + Node *new = malloc(sizeof(Node)); + + new->data = val; + new->degree = 0; + new->child = new->parent = new->sibling = NULL; + + return new; +} + +list *unionList(list *l1, list *l2) { + list *l = newList(); + + int i = 0, j = 0; + + while (i < l1->size && j < l2->size) { + // push the one with smaller degree first + if (l1->arr[i]->degree <= l2->arr[j]->degree) { + pushBack(l, l1->arr[i]); + i++; + } else { + pushBack(l, l2->arr[j]); + j++; + } + } + + while (i < l1->size) { + pushBack(l, l1->arr[i]); + i++; + } + + while (j < l2->size) { + pushBack(l, l2->arr[j]); + j++; + } + return l; +} + +Node *merge(Node *l, Node *r) { + if (l->data > r->data) { + swapNode(l, r); + } + + r->parent = l; + r->sibling = l->child; + + l->child = r; + l->degree++; + + return l; +} + +list *adjust(list *l) { + if (l->size <= 1) { + return l; + } + + int i = 0, j = 0, k = 0; + + if (l->size == 2) { + j = i + 1; + k = l->size; + } else { + j++; + k = j + 1; + } + + // can't use i != size here, since the list will shrink. + while (i < l->size) { + // only one element remains + if (j == l->size) { + i++; + } else if (l->arr[i]->degree < l->arr[j]->degree) { + i++; + j++; + if (k < l->size) { + k++; + } + } else if (k < l->size && l->arr[i]->degree == l->arr[j]->degree && + l->arr[i]->degree == l->arr[k]->degree) { + i++; + j++; + k++; + } else if (l->arr[i]->degree == l->arr[j]->degree) { + l->arr[i] = merge(l->arr[i], l->arr[j]); + erase(l, j); + if (k < l->size) { + k++; + } + } + } + + return l; +} + +list *insertTree(list *l, Node *tree) { + list *temp = newList(); + + pushBack(temp, tree); + + temp = unionList(l, temp); + + return adjust(temp); +} + +list *insert(list *l, int key) { + Node *temp = newNode(key); + return insertTree(l, temp); +} + +void traverseLevel(Node* h, int level) { + if (h) { + traverseLevel(h->sibling, level); + if (level == 1) { + printf("%d,", h->data); + } else { + traverseLevel(h->child, level - 1); + } + } +} + +void printTree(Node *h) { + int i = 0; + for (Node* ptr = h; ptr != NULL; ptr = ptr->child) { + i++; + traverseLevel(h, i); + } +} + +void printHeap(list *l, int k) { + int present = 0; + for (int i = 0; i < l->size; i++) { + if (l->arr[i]->degree == k) { + printTree(l->arr[i]); + present = 1; + } + } + + if (present == 0) { + printf("0,"); + } +} + +int getDigits(int i) { + int count = 0; + while (i) { + count ++; + i /= 10; + } + + return count; +} + +int main(void) { + list *l = newList(); + + char buf[MAX]; + scanf("%s", buf); + int tmp, offset = 0; + + while (sscanf(buf + offset, "%d,", &tmp) != EOF) { + // printf("%d is scanned, offset: %d\n", tmp, offset); + l = insert(l, tmp); + offset += getDigits(tmp) + 1; + } + + int treeNum; + + scanf("%d", &treeNum); + + printHeap(l, treeNum); + + return 0; +}