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