Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions Homework10/2018202045DHP/Makefile
Original file line number Diff line number Diff line change
@@ -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
249 changes: 249 additions & 0 deletions Homework10/2018202045DHP/RBTree.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
#include "RBTree.h"
#include <stdio.h>
#include <malloc.h>

//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);
}

32 changes: 32 additions & 0 deletions Homework10/2018202045DHP/RBTree.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include <stdio.h>
#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);
24 changes: 24 additions & 0 deletions Homework10/2018202045DHP/data.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include <stdio.h>
#include <stdlib.h>
#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;
}
24 changes: 24 additions & 0 deletions Homework10/2018202045DHP/main_comp.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include "RBTree.h"
#include <stdio.h>
#include <stdlib.h>

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;
}
13 changes: 13 additions & 0 deletions Homework10/2018202045DHP/main_deco.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include "RBTree.h"
#include <stdio.h>
#include <stdlib.h>

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;
}