Name: Anonymous 2012-02-06 17:01
See title.
#include <malloc.h>
#include <assert.h>
#include <stdio.h>
#include "trace.h"
#include "utils.h"
#include "tree.h"
p tree_vtable[] = {
(p)destroy_tree,
(p)print_tree
};
v init_tree(p self, p item, p left, p right) {C
P("init_tree: %p to ", self); PS(item); P(", "); PS(left); P(", "); PS(right); P("\n");
init_object(self, tree_vtable);
init_fields_tree(self, item, left, right);
R}
v init_fields_tree(p self, p item, p left, p right) {C
P("init_fields_tree: %p to ", self); PS(item); P(", "); PS(left); P(", "); PS(right); P("\n");
init(&((struct tree*)self)->item, item);
init(&((struct tree*)self)->left, left);
init(&((struct tree*)self)->right, right);
R}
p tree(p item, p left, p right) {C
P("tree: "); PS(item); P(", "); PS(left); P(", "); PS(right); P("\n");
p allocation = malloc(sizeof(struct tree));
assert(allocation);
init_tree(allocation, item, left, right);
R return allocation;
}
v set_left_tree(p self, p left) {C
P("set_left_tree: %p to \n", self); PS(left); P("\n");
set(&((struct tree*)self)->left, left);
R}
v set_right_tree(p self, p right) {C
P("set_right_tree: %p to \n", self); PS(right); P("\n");
set(&((struct tree*)self)->right, right);
R}
v set_item_tree(p self, p item) {C
P("set_item_tree: %p to \n", self); PS(item); P("\n");
set(&((struct tree*)self)->item, item);
R}
p left_tree(p self) {C
P("left_tree: %p", self); P("\n");
R return ((struct tree*)self)->left;
}
p right_tree(p self) {C
P("right_tree: %p", self); P("\n");
R return ((struct tree*)self)->right;
}
p item_tree(p self) {C
P("item_tree: %p", self); P("\n");
R return ((struct tree*)self)->item;
}
v destroy_tree(p self) {C
P("destroy_tree: %p", self); P("\n");
unreg(item_tree(self));
unreg(left_tree(self));
unreg(right_tree(self));
R}
v print_tree(FILE* output, p self) {
fprintf(output, "<tree>");
fprintf(output, "<item>");
print_object(output, item_tree(self));
fprintf(output, "</item>");
fprintf(output, "<left>");
print_object(output, left_tree(self));
fprintf(output, "</left>");
fprintf(output, "<right>");
print_object(output, right_tree(self));
fprintf(output, "</right>");
fprintf(output, "</tree>");
}
p merge_trees(p tree_left, p tree_right, int take_tree_right, p(*tree_constructor)(p,p,p)) {C
P("merge_trees: "); PS(tree_left); P(", "); PS(tree_right); P(" %d\n", take_tree_right);
if(!tree_left) {
R return tree_right;
} else if(!tree_right) {
R return tree_left;
} else if(!right_tree(tree_left)) {
R return tree_constructor(item_tree(tree_left), left_tree(tree_left), tree_right);
} else if(!left_tree(tree_right)) {
R return tree_constructor(item_tree(tree_right), tree_left, right_tree(tree_right));
} else if(take_tree_right) {
R return tree_constructor(item_tree(tree_right), merge_trees(tree_left, left_tree(tree_right), 0, tree_constructor), right_tree(tree_right));
} else {
R return tree_constructor(item_tree(tree_left), left_tree(tree_left), merge_trees(right_tree(tree_left), tree_right, 1, tree_constructor));
}
}
// The root will go down to the left. It's right child becomes the parent.
// The right child must not be null.
p rotate_left_tree(p root, p(*tree_constructor)(p,p,p)) {
p right_root = right_tree(root);
assert(right_root);
return tree_constructor(item_tree(right_root),
tree_constructor(item_tree(root),
left_tree(root),
left_tree(right_root)),
right_tree(right_root))
}
// The root will move down to the right, with its former left child becoming the root's parent.
// The left child must not be null.
p rotate_right_tree(p root, p(*tree_constructor)(p,p,p)) {
p left_root = left_tree(root);
assert(left_root);
return tree_constructor(item_tree(left_root),
left_tree(left_root),
tree_constructor(item_tree(root),
right_tree(left_root),
right_tree(root)));
}
int height_tree(p root) {
if(!root) return 0;
return max(height_tree(left_tree(root)), height_tree(right_tree(root))) + 1;
}
int size_tree(p root) {
if(!root) return 0;
return 1 + size_tree(left_tree(root)) + size_tree(right_tree(root));
}
int
).