Archived
1
0
Fork 0

tree: Adding N-tree module.

This commit is contained in:
Henrik Hautakoski 2011-02-14 08:09:42 +01:00
parent 546e7c50f1
commit 171c764691
4 changed files with 396 additions and 0 deletions

119
src/tree.c Normal file
View file

@ -0,0 +1,119 @@
/* tree.c - N-tree implementation
*
* Copyright (C) 2011 Henrik Hautakoski <henrik@fiktivkod.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Generic implementation of a N-tree
*/
#include "xalloc.h"
#include "tree.h"
struct tree* tree_new() {
return xmallocz(sizeof(struct tree));
}
struct tree* tree_link(struct tree *parent, struct tree *tree) {
if (parent->child) {
struct tree *it = parent->child;
while(it->next)
it = it->next;
it->next = tree;
} else {
parent->child = tree;
}
tree->parent = parent;
return tree;
}
void tree_unlink(struct tree *tree) {
if (tree_is_root(tree))
return;
/* remove the node from the tree */
if (tree->parent->child == tree) {
tree->parent->child = tree->next;
} else {
struct tree *prev = tree->parent->child;
while(prev->next && prev->next != tree)
prev = prev->next;
prev->next = tree->next;
}
/* move the children to node's old parent */
if (tree->child) {
struct tree *it = tree->parent->child;
if (tree->parent->child) {
while(it->next)
it = it->next;
it->next = tree->child;
} else {
tree->parent->child = tree->child;
}
/* Update parent */
for(it = tree->child; it; it = it->next)
it->parent = tree->parent;
}
tree->parent = NULL;
tree->next = NULL;
tree->child = NULL;
}
void tree_move(struct tree *dest, struct tree *src) {
if (src->parent == dest)
/* node are already in place */
return;
/* detach and attach att the new node */
tree_detach(src);
tree_link(dest, src);
}
void tree_detach(struct tree *tree) {
if (tree_is_root(tree))
return;
if (tree->parent->child == tree) {
tree->parent->child = tree->next;
} else if (tree->parent->child) {
struct tree *prev = tree->parent->child;
while(prev->next && prev->next != tree)
prev = prev->next;
prev->next = tree->next;
}
tree->parent = NULL;
tree->next = NULL;
}
void tree_traverse(struct tree *tree, tree_traverse_fn fn, void *data) {
while(tree) {
struct tree *next = tree->next;
fn(tree, data);
if (tree->child)
tree_traverse(tree->child, fn, data);
tree = next;
}
}
size_t tree_parent_count(struct tree *tree) {
size_t count = 0;
if (tree) {
for(; tree->parent; count++)
tree = tree->parent;
}
return count;
}

48
src/tree.h Normal file
View file

@ -0,0 +1,48 @@
/* tree.c - N-tree implementation
*
* Copyright (C) 2011 Henrik Hautakoski <henrik@fiktivkod.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*/
#ifndef __TREE_H
#define __TREE_H
#include <stddef.h>
struct tree {
struct tree *next;
struct tree *parent;
struct tree *child;
};
typedef void (*tree_traverse_fn)(struct tree *tree, void *data);
#define tree_is_root(n) \
((n) && \
(n)->parent == NULL && \
(n)->next == NULL)
#define tree_is_leaf(n) \
((n) && (n)->child == NULL)
#define TREE_INIT { NULL }
struct tree* tree_new();
struct tree* tree_link(struct tree *parent, struct tree *tree);
void tree_unlink(struct tree *tree);
void tree_move(struct tree *dest, struct tree *src);
void tree_detach(struct tree *tree);
void tree_traverse(struct tree *tree, tree_traverse_fn fn, void *data);
size_t tree_parent_count(struct tree *tree);
#endif /* __TREE_H */