From ac4e6420ec30d27c9d81dc89a0ad89b23b02ace1 Mon Sep 17 00:00:00 2001 From: ru1eR0 <810496106@qq.com> Date: Tue, 22 Jan 2019 16:39:42 +0800 Subject: [PATCH] homework submission by DHP --- Homework10/2018202045DHP/Makefile | 8 + Homework10/2018202045DHP/RBTree.c | 249 +++++++++++++++++++++++++++ Homework10/2018202045DHP/RBTree.h | 32 ++++ Homework10/2018202045DHP/data.c | 24 +++ Homework10/2018202045DHP/main_comp.c | 24 +++ Homework10/2018202045DHP/main_deco.c | 13 ++ 6 files changed, 350 insertions(+) create mode 100644 Homework10/2018202045DHP/Makefile create mode 100644 Homework10/2018202045DHP/RBTree.c create mode 100644 Homework10/2018202045DHP/RBTree.h create mode 100644 Homework10/2018202045DHP/data.c create mode 100644 Homework10/2018202045DHP/main_comp.c create mode 100644 Homework10/2018202045DHP/main_deco.c diff --git a/Homework10/2018202045DHP/Makefile b/Homework10/2018202045DHP/Makefile new file mode 100644 index 0000000..bb72203 --- /dev/null +++ b/Homework10/2018202045DHP/Makefile @@ -0,0 +1,8 @@ +data : data.c + gcc data.c -o data +comp : main_comp.c RBTree.c RBTree.h + gcc main_comp.c RBTree.c -o comp +deco : main_deco.c RBTree.c RBTree.h + gcc main_deco.c RBTree.c -o deco +clean : + rm comp deco data diff --git a/Homework10/2018202045DHP/RBTree.c b/Homework10/2018202045DHP/RBTree.c new file mode 100644 index 0000000..e90f580 --- /dev/null +++ b/Homework10/2018202045DHP/RBTree.c @@ -0,0 +1,249 @@ +#include "RBTree.h" +#include +#include + +//double min(double x,double y){return x > y ? y : x;} +//double max(double x,double y){return x > y ? x : y;} + +static struct RBTree nil; +static struct RBTree *root = NULL; + +struct RBTree *newnode(double val, char ch, int siz, int col, struct RBTree *left, struct RBTree *right, struct RBTree *p){ + struct RBTree *temp = (struct RBTree *) malloc(sizeof(struct RBTree)); + temp->val = val; + temp->ch = ch; + temp->siz = siz; + temp->col = col; + temp->left = (left == NULL) ? &nil : left; + temp->right = (right == NULL) ? &nil : right; + temp->p = (p == NULL) ? &nil : p; + return temp; +} + +int isempty(){ + return (root == NULL) || (root == &nil); +} + +void outit(struct RBTree *x, FILE **fo){ + fprintf(*fo, "val:%.3lf ch:%c col:%d\n", x->val, x->ch, x->col); + fprintf(*fo, "leftchild:%s\n", x->left == &nil? "NO" : "YES"); + fprintf(*fo, "rightchild:%s\n", x->right == &nil? "NO" : "YES"); + fprintf(*fo, "\n"); + if(x->left != &nil) + outit(x->left, fo); + if(x->right != &nil) + outit(x->right, fo); +} + +void create(double x,char ch){ + nil.val = 0; nil.siz = 0; nil.col = 1; + nil.left = nil.right = nil.p = &nil; + root = newnode(x, ch, 1, 1, &nil, &nil, &nil); +} + + +static void totally_delete(struct RBTree *x){ + if(x == &nil)return; + totally_delete(x->left); + totally_delete(x->right); + free(x); +} + +void destroy(){ + totally_delete(root); +} + +void update(struct RBTree *x){ + x->siz = (x->left->siz) + (x->right->siz) + 1; +} + +void left_rotate(struct RBTree *x){ + struct RBTree *y = x->right; + x->right = y->left; + if(y->left != &nil) + y->left->p = x; + y->p = x->p; + if(x->p == &nil) + root = y; + else if(x == x->p->left) + x->p->left= y; + else x->p->right = y; + y->left = x; + x->p = y; + update(x);update(y); +} + +void right_rotate(struct RBTree *x){ + struct RBTree *y = x->left; + x->left = y->right; + if(y->right != &nil) + y->right->p = x; + y->p = x->p; + if(x->p == &nil) + root = y; + else if(x == x->p->right) + x->p->right = y; + else x->p->left= y; + y->right = x; + x->p = y; + update(x);update(y); +} + +void insert_fixup(struct RBTree *z){ + struct RBTree *y; + while(z->p->col == 0){ + if(z->p == z->p->p->left){ + y = z->p->p->right; + if(y->col == 0){ + z->p->col = 1; + y->col = 1; + z->p->p->col = 0; + z = z->p->p; + }else{ + + if(z == z->p->right){ + z = z->p; + left_rotate(z); + } + z->p->col = 1; + z->p->p->col = 0; + right_rotate(z->p->p); + } + }else { + y = z->p->p->left; + if(y->col == 0){ + z->p->col = 1; + y->col = 1; + z->p->p->col = 0; + z = z->p->p; + }else{ + if(z == z->p->left){ + z = z->p; + right_rotate(z); + } + z->p->col = 1; + z->p->p->col = 0; + left_rotate(z->p->p); + } + } + } + root->col = 1; +} + +void insert(struct RBTree *z){ + + struct RBTree *y = &nil; + struct RBTree *x = root; + while (x != &nil){ + y = x; + x->siz++; + if(z->val < x->val) + x = x->left; + else x = x->right; + } + z -> p = y; + if (y == &nil) + root = z; + else if (z->val < y->val) + y->left = z; + else y->right = z; + z->left = z->right = &nil; + z->col = 0; + insert_fixup(z); +} + +void transplant(struct RBTree *u, struct RBTree *v){ + if(u->p == &nil) + root = v; + else if(u == u->p->left) + u->p->left = v; + else u->p->right = v; + v->p = u->p; +// freeall(v); +} + + +//these functions are designed for the homework especially +//any constant in these functions are formulated elaborately + +double Abs(double x){ + return x>0?x:-x; +} + +void traversal(struct RBTree *x, FILE **fp){ + unsigned int oump; + oump =((int)Abs (x->val * 10000) + 1) / 10; + if(x->val < 0) oump |= 1u << 31; + int chmp; + if(x->ch >= 'A' && x->ch <= 'Z') chmp = x->ch - 'A'; + else chmp = x->ch - 'a' + 26; + oump |= chmp << 24; + oump |= x->col << 30; + fwrite(&oump, 4, 1, *fp); +// if((oump & 0x00ffffff) == 0x007ef269) fprintf(stderr, "%.6lf %d\n", x->val, oump&0x00ffffff); + if(x->left != &nil) traversal(x->left, fp); + if(x->right != &nil) traversal(x->right, fp); +} + +void compress(FILE *fp, FILE *fo){ + outit(root, &fo); + traversal(root, &fp); +} + +unsigned int resolve(struct RBTree *x, FILE **fp, double llim, double rlim,unsigned int gotva){ + if(gotva == 0xffffffffu) + if(fread(&gotva, 4, 1, *fp) == 0) + return -1; +// fprintf(stderr, "%x\n", gotva); +// printf("ha1\n"); + unsigned int inmp = gotva & 0x80ffffffu; + int chmp = (gotva & 0x3f000000) >> 24; + int col = (gotva & 0x40000000) >> 30; + char ch = chmp <= 25 ? chmp + 'A' : chmp + 'a' -26; + double db = inmp % (1u << 31) / 1000.0; + if(inmp > (1u << 31)) db *= -1; +// printf("%.3f %c %d %.3f %.3f\n", db, ch, col, llim, rlim); + + if(db > llim && db < rlim && db < x->val){ + x->left = newnode(db, ch, 1, col, &nil, &nil, x); + gotva = resolve(x->left, fp, llim, x->val, 0xffffffffu); + } + + if(gotva == 0xffffffffu) + if(fread(&gotva, 4, 1, *fp) == 0) + return -1; +// fprintf(stderr, "%x\n", gotva); +// printf("ha2\n"); + inmp = gotva & 0x80ffffffu; + chmp = (gotva & 0x3f000000) >> 24; + col = (gotva & 0x40000000) >> 30; + ch = chmp <= 25 ? chmp + 'A' : chmp + 'a' -26; + db = inmp % (1u << 31) / 1000.0; + if(inmp > (1u << 31)) db *= -1; +// printf("%.3f %c %d %.3f %.3f\n", db, ch, col, llim, rlim); + + if(db > llim && db < rlim && db > x->val){ + x->right = newnode(db, ch, 1, col, &nil, &nil, x); + gotva = resolve(x->right, fp, x->val, rlim, 0xffffffffu); + } + update(x); + return gotva; +} + +void decompress(FILE *fp, FILE *fo){ + if(root != NULL) destroy(root); + int gotva; + fread(&gotva, 4, 1, fp); +// fprintf(stderr, "%x\n", gotva); + //s c hhhhhh vvvvvvvvvvvvvvvvvvvvvvvv + unsigned int inmp = gotva & 0x80ffffff; + int chmp = (gotva & 0x3f000000u) >> 24; + char ch = chmp <= 25 ? chmp + 'A' : chmp + 'a' - 26; + double db = inmp % (1u << 31) / 1000.0; + if(inmp > (1u << 31)) db *= -1; +// printf("%f %c\n", db, ch); + create(db, ch); + resolve(root, &fp, -10001.0, 10001.0, 0xffffffffu); + outit(root, &fo); +} + diff --git a/Homework10/2018202045DHP/RBTree.h b/Homework10/2018202045DHP/RBTree.h new file mode 100644 index 0000000..82d2dc4 --- /dev/null +++ b/Homework10/2018202045DHP/RBTree.h @@ -0,0 +1,32 @@ +#include +#define MAXAX 1000000010 + +struct RBTree{ + double val; + char ch; + int siz, col; + struct RBTree *left, *right, *p; +}; + +//double min(double x,double y); +//double max(double x,double y); + +struct RBTree *newnode(double val, char ch, int siz, int col, struct RBTree *left, struct RBTree *right, struct RBTree *p); + +int isempty(); +void outit(struct RBTree *x, FILE **fo); + +void create(double x, char ch); +void destroy(); + +void update(struct RBTree *x); +void left_rotate(struct RBTree *x); +void right_rotate(struct RBTree *x); + +void insert_fixup(struct RBTree *z); +void insert(struct RBTree *z); + +void transplant(struct RBTree *u, struct RBTree *v); + +void compress(FILE *fp, FILE *fo); +void decompress(FILE *fp, FILE *fo); diff --git a/Homework10/2018202045DHP/data.c b/Homework10/2018202045DHP/data.c new file mode 100644 index 0000000..5c11c71 --- /dev/null +++ b/Homework10/2018202045DHP/data.c @@ -0,0 +1,24 @@ +#include +#include +#define N 300000 +#define LIM 20000000 +int def[LIM + 10]; + +int main(){ + freopen("data.in", "w", stdout); + printf("%d\n", N); + for(int i=1; i<=N; i++){ + int val = rand()%LIM; + while(def[val]) { + //fprintf(stderr, "%d\n crashed", val); + //if(val == (-8319593) + LIM/2) fprintf(stderr, "err\n"); + val = rand()%LIM; + } + def[val] = 1; + char ch = rand()%52; + if(ch <= 25) ch += 'A'; + else ch = ch - 26 + 'a'; + printf("%.3lf %c\n",(val-LIM/2) / 1000.0, ch); + } + return 0; +} diff --git a/Homework10/2018202045DHP/main_comp.c b/Homework10/2018202045DHP/main_comp.c new file mode 100644 index 0000000..3e58798 --- /dev/null +++ b/Homework10/2018202045DHP/main_comp.c @@ -0,0 +1,24 @@ +#include "RBTree.h" +#include +#include + +int main(){ + int n; + double x; + char ch; + FILE *in = fopen("data.in","r"); + FILE *fp = fopen("RBTsaver.bin","w"); + FILE *fo = fopen("RBTshape.out","w"); + fscanf(in, "%d", &n); + for(int i = 1;i <= n; i++){ + fscanf(in, "%lf %c", &x, &ch); + if(i == 1) create(x, ch); + else insert(newnode(x, ch, 1, 0, NULL, NULL, NULL)); + } + compress(fp, fo); + destroy(); + fclose(in); + fclose(fp); + fclose(fo); + return 0; +} diff --git a/Homework10/2018202045DHP/main_deco.c b/Homework10/2018202045DHP/main_deco.c new file mode 100644 index 0000000..2938ad4 --- /dev/null +++ b/Homework10/2018202045DHP/main_deco.c @@ -0,0 +1,13 @@ +#include "RBTree.h" +#include +#include + +int main(){ + FILE *fp = fopen("RBTsaver.bin","r"); + FILE *fo = fopen("RBTshape_decompressed.out","w"); + decompress(fp, fo); + destroy(); + fclose(fp); + fclose(fo); + return 0; +}