124 lines
2.8 KiB
C
124 lines
2.8 KiB
C
#include "sortedmap.h"
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
struct intern {
|
|
enum nodetype type;
|
|
char * key;
|
|
struct node * left;
|
|
struct node * right;
|
|
};
|
|
|
|
struct leaf {
|
|
enum nodetype type;
|
|
char * key;
|
|
void * value;
|
|
};
|
|
|
|
SortedMap * map() {
|
|
return NULL;
|
|
}
|
|
|
|
void * get_map(SortedMap *this, char *key) {
|
|
if (this == NULL) return NULL;
|
|
if (this->type == LEAF) {
|
|
if (strcmp(key, this->key) == 0) return ((struct leaf *) this)->value;
|
|
return NULL;
|
|
} else {
|
|
if (strcmp(key, this->key) <= 0) {
|
|
return get_map(((struct intern *) this)->left, key);
|
|
} else {
|
|
return get_map(((struct intern *) this)->right, key);
|
|
}
|
|
}
|
|
}
|
|
|
|
SortedMap * put_map(SortedMap *this, char *key, void *value) {
|
|
struct leaf *leaf, *newleaf;
|
|
struct intern *intern;
|
|
int cmp;
|
|
|
|
if (this == NULL) {
|
|
struct leaf *leaf = malloc(sizeof(struct leaf));
|
|
leaf->type = LEAF;
|
|
leaf->key = key;
|
|
leaf->value = value;
|
|
return (SortedMap *) leaf;
|
|
} else {
|
|
cmp = strcmp(key, this->key);
|
|
if (this->type == LEAF) {
|
|
leaf = (struct leaf*) this;
|
|
if (cmp == 0) {
|
|
leaf->value = value;
|
|
return (SortedMap *) leaf;
|
|
}
|
|
newleaf = malloc(sizeof(struct leaf));
|
|
newleaf->type = LEAF;
|
|
newleaf->key = key;
|
|
newleaf->value = value;
|
|
intern = malloc(sizeof(struct intern));
|
|
intern->type = INTERN;
|
|
intern->key = leaf->key;
|
|
intern->left = (struct node*) (cmp < 0 ? newleaf : leaf);
|
|
intern->right = (struct node*) (cmp < 0 ? leaf : newleaf);
|
|
return (SortedMap *) intern;
|
|
} else {
|
|
intern = (struct intern*) this;
|
|
if (cmp <= 0) {
|
|
intern->left = put_map(intern->left, key, value);
|
|
return (SortedMap *) intern;
|
|
} else {
|
|
intern->right = put_map(intern->right, key, value);
|
|
return (SortedMap *) intern;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void print_indent_(int indent) {
|
|
int i;
|
|
for(i = 0; i < indent; i++) printf(" ");
|
|
}
|
|
|
|
void print_map_(SortedMap *this, int indent) {
|
|
if (this->type == LEAF) {
|
|
struct leaf *leaf = (struct leaf*) this;
|
|
print_indent_(indent);
|
|
printf("%s: %s\n", leaf->key, (char *) leaf->value);
|
|
} else {
|
|
struct intern *intern = (struct intern*) this;
|
|
print_map_(intern->left, indent + 1);
|
|
print_indent_(indent);
|
|
printf("%s\n", intern->key);
|
|
print_map_(intern->right, indent + 1);
|
|
}
|
|
}
|
|
|
|
void print_map(SortedMap *this) {
|
|
if (this == NULL) printf("empty\n");
|
|
else print_map_(this, 0);
|
|
}
|
|
|
|
void free_mapvalues(SortedMap *this) {
|
|
if (this == NULL) return;
|
|
else if (this->type == LEAF) free(((struct leaf*) this)->value);
|
|
else {
|
|
struct intern *intern = (struct intern*) this;
|
|
free_mapvalues(intern->left);
|
|
free_mapvalues(intern->right);
|
|
}
|
|
}
|
|
|
|
void free_map(SortedMap *this) {
|
|
struct intern *intern;
|
|
if (this == NULL) return;
|
|
else if (this->type == LEAF) free(this);
|
|
else {
|
|
intern = (struct intern*) this;
|
|
free_map(intern->left);
|
|
free_map(intern->right);
|
|
free(this);
|
|
}
|
|
}
|