[GRASS-SVN] r55362 - in grass/trunk: include/defs lib/btree2
svn_grass at osgeo.org
svn_grass at osgeo.org
Wed Mar 13 07:43:24 PDT 2013
Author: mmetz
Date: 2013-03-13 07:43:24 -0700 (Wed, 13 Mar 2013)
New Revision: 55362
Modified:
grass/trunk/include/defs/rbtree.h
grass/trunk/lib/btree2/rbtree.c
Log:
rbtree: add backward traversal
Modified: grass/trunk/include/defs/rbtree.h
===================================================================
--- grass/trunk/include/defs/rbtree.h 2013-03-13 14:40:22 UTC (rev 55361)
+++ grass/trunk/include/defs/rbtree.h 2013-03-13 14:43:24 UTC (rev 55362)
@@ -12,6 +12,7 @@
/* tree traversal functions */
int rbtree_init_trav(struct RB_TRAV *, struct RB_TREE *);
void* rbtree_traverse(struct RB_TRAV *);
+void *rbtree_traverse_backwd(struct RB_TRAV *trav);
void *rbtree_traverse_start(struct RB_TRAV *, const void *);
/* debug tree from given node downwards */
Modified: grass/trunk/lib/btree2/rbtree.c
===================================================================
--- grass/trunk/lib/btree2/rbtree.c 2013-03-13 14:40:22 UTC (rev 55361)
+++ grass/trunk/lib/btree2/rbtree.c 2013-03-13 14:43:24 UTC (rev 55362)
@@ -37,7 +37,9 @@
static struct RB_NODE *rbtree_single(struct RB_NODE *, int);
static struct RB_NODE *rbtree_double(struct RB_NODE *, int);
static void *rbtree_first(struct RB_TRAV *);
+static void *rbtree_last(struct RB_TRAV *trav);
static void *rbtree_next(struct RB_TRAV *);
+static void *rbtree_previous(struct RB_TRAV *);
static struct RB_NODE *rbtree_make_node(size_t, void *);
static int is_red(struct RB_NODE *);
@@ -297,6 +299,32 @@
}
}
+/* traverse the tree in descending order
+ * useful to get all items in the tree non-recursively
+ * struct RB_TRAV *trav needs to be initialized first
+ * returns pointer to data, NULL when finished
+ */
+void *rbtree_traverse_backwd(struct RB_TRAV *trav)
+{
+ assert(trav);
+
+ if (trav->curr_node == NULL) {
+ if (trav->first)
+ G_debug(1, "RB tree: empty tree");
+ else
+ G_debug(1, "RB tree: finished traversing");
+
+ return NULL;
+ }
+
+ if (!trav->first)
+ return rbtree_previous(trav);
+ else {
+ trav->first = 0;
+ return rbtree_last(trav);
+ }
+}
+
/* find start point to traverse the tree in ascending order
* useful to get a selection of items in the tree
* magnitudes faster than traversing the whole tree
@@ -359,7 +387,7 @@
/* start traversing the tree
* returns pointer to smallest data item
*/
-void *rbtree_first(struct RB_TRAV *trav)
+static void *rbtree_first(struct RB_TRAV *trav)
{
/* get smallest item */
while (trav->curr_node->link[0] != NULL) {
@@ -370,6 +398,20 @@
return trav->curr_node->data; /* return smallest item */
}
+/* start traversing the tree
+ * returns pointer to largest data item
+ */
+static void *rbtree_last(struct RB_TRAV *trav)
+{
+ /* get smallest item */
+ while (trav->curr_node->link[1] != NULL) {
+ trav->up[trav->top++] = trav->curr_node;
+ trav->curr_node = trav->curr_node->link[1];
+ }
+
+ return trav->curr_node->data; /* return smallest item */
+}
+
/* continue traversing the tree in ascending order
* returns pointer to data item, NULL when finished
*/
@@ -407,6 +449,43 @@
return NULL; /* finished traversing */
}
+/* continue traversing the tree in descending order
+ * returns pointer to data item, NULL when finished
+ */
+void *rbtree_previous(struct RB_TRAV *trav)
+{
+ if (trav->curr_node->link[0] != NULL) {
+ /* something on the left side: smaller item */
+ trav->up[trav->top++] = trav->curr_node;
+ trav->curr_node = trav->curr_node->link[0];
+
+ /* go down, find largest item in this branch */
+ while (trav->curr_node->link[1] != NULL) {
+ trav->up[trav->top++] = trav->curr_node;
+ trav->curr_node = trav->curr_node->link[1];
+ }
+ }
+ else {
+ /* at largest item in this branch, go back up */
+ struct RB_NODE *last;
+
+ do {
+ if (trav->top == 0) {
+ trav->curr_node = NULL;
+ break;
+ }
+ last = trav->curr_node;
+ trav->curr_node = trav->up[--trav->top];
+ } while (last == trav->curr_node->link[0]);
+ }
+
+ if (trav->curr_node != NULL) {
+ return trav->curr_node->data;
+ }
+ else
+ return NULL; /* finished traversing */
+}
+
/* clear the tree, removing all entries */
void rbtree_clear(struct RB_TREE *tree)
{
More information about the grass-commit
mailing list