123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- /*************************************************************
- * USAGE *
- *************************************************************
- *
- * NOTE: duplicates are not supported
- *
- * custom compare function
- * extern int my_compare_fn(const void *, const void *);
- * int my_compare_fn(const void *a, const void *b) {
- * if ((mydatastruct *) a < (mydatastruct *) b)
- * return -1;
- * else if ((mydatastruct *) a > (mydatastruct *) b)
- * return 1;
- * else if ((mydatastruct *) a == (mydatastruct *) b)
- * return 0;
- * }
- *
- * create and initialize tree:
- * struct RG_TREE *mytree = rgtree_create(my_compare_fn, item_size);
- *
- * insert items to tree:
- * struct mydatastruct data = <some data>;
- * if (rgtree_insert(mytree, &data) == 0)
- * G_warning("could not insert data");
- *
- * find item in tree:
- * struct mydatastruct data = <some data>;
- * if (rgtree_find(mytree, &data) == 0)
- * G_message("data not found");
- *
- * delete item from tree:
- * struct mydatastruct data = <some data>;
- * if (rgtree_remove(mytree, &data) == 0)
- * G_warning("could not find data in tree");
- *
- * traverse tree (get all items in tree in ascending order):
- * struct RG_TRAV trav;
- * rgtree_init_trav(&trav, tree);
- * while ((data = rgtree_traverse(&trav)) != NULL) {
- * if (my_compare_fn(data, threshold_data) == 0) break;
- * <do something with data>;
- * }
- *
- * get a selection of items: all data > data1 and < data2
- * start in tree where data is last smaller or first larger compared to data1
- * struct RG_TRAV trav;
- * rgtree_init_trav(&trav, tree);
- * data = rgtree_traverse_start(&trav, &data1);
- * <do something with data>;
- * while ((data = rgtree_traverse(&trav)) != NULL) {
- * if (data > data2) break;
- * <do something with data>;
- * }
- *
- * destroy tree:
- * rgtree_destroy(mytree);
- *
- * debug the whole tree with
- * rgtree_debug(mytree, mytree->root);
- *
- *************************************************************/
- #ifndef REGTREE_H
- #define REGTREE_H
- #include <stddef.h>
- /* maximum RB Tree height */
- #define REGTREE_MAX_HEIGHT 64 /* should be more than enough */
- /* routine to compare data items
- * return -1 if rb_a < rb_b
- * return 0 if rb_a == rb_b
- * return 1 if rb_a > rb_b
- */
- struct reg_stats
- {
- int id; /* region ID */
- int count; /* number of cells of this region */
- double *sum, /* sum for each band */
- *mean; /* mean for each band = sum[b] / count */
- /* unused; stddev and thus sumsq may be needed for
- * eCognition-like multi-scale segmentation */
- /*
- *min,
- *max,
- *sumsq,
- *stddev;
- */
- };
- typedef int rg_compare_fn(struct reg_stats *rb_a, struct reg_stats *rb_b);
- struct RG_NODE
- {
- unsigned char red; /* 0 = black, 1 = red */
- struct RG_NODE *link[2]; /* link to children: link[0] for smaller, link[1] for larger */
- struct reg_stats data; /* any kind of data */
- };
-
- struct RG_TREE
- {
- struct RG_NODE *root; /* root node */
- size_t datasize; /* item size */
- size_t count; /* number of items in tree. */
- int nbands; /* number of bands */
- rg_compare_fn *cmp; /* function to compare data */
- };
- struct RG_TRAV
- {
- struct RG_TREE *tree; /* tree being traversed */
- struct RG_NODE *curr_node; /* current node */
- struct RG_NODE *up[REGTREE_MAX_HEIGHT]; /* stack of parent nodes */
- int top; /* index for stack */
- int first; /* little helper flag */
- };
- /* tree functions */
- struct RG_TREE *rgtree_create(int, size_t);
- void rgtree_destroy(struct RG_TREE *);
- int rgtree_insert(struct RG_TREE *, struct reg_stats *);
- int rgtree_remove(struct RG_TREE *, struct reg_stats *);
- struct reg_stats *rgtree_find(struct RG_TREE *, struct reg_stats *);
- /* tree traversal functions */
- int rgtree_init_trav(struct RG_TRAV *, struct RG_TREE *);
- struct reg_stats *rgtree_traverse(struct RG_TRAV *);
- struct reg_stats *rgtree_traverse_start(struct RG_TRAV *, struct reg_stats *);
- /* debug tree from given node downwards */
- int rgtree_debug(struct RG_TREE *, struct RG_NODE *);
- #endif
|