int RbTraverseDown (RBTREE tree, RBKEY low, RBKEY high, void *param, TraverseFuncType TraverseFunc) { RBNODE nil=tree->nil; RBNODE x=tree->root->left; RBNODE lastBest=nil; int rtn=1; /* Find starting location */ while(nil != x) { if ( 0 < (TreeCompare(tree, x->key, high)) ) { /* x->key > high */ x=x->left; } else { lastBest=x; x=x->right; } } /* Now traverse, watching for ending location */ while ( (lastBest != nil) && (0 >= TreeCompare(tree, low, lastBest->key))) { rtn = (*TraverseFunc)(lastBest->key, lastBest->info, param); if (!rtn) return rtn; lastBest=RbTreePredecessor(tree,lastBest); } return rtn; }
static void TreeInsertHelp (RBTREE tree, RBNODE z) { /* This function should only be called by InsertRbTree (see above) */ RBNODE x; RBNODE y; RBNODE nil=tree->nil; z->left=z->right=nil; y=tree->root; x=tree->root->left; while( x != nil) { y=x; if (0 < TreeCompare(tree, x->key,z->key)) { /* x.key > z.key */ x=x->left; } else { /* x,key <= z.key */ x=x->right; } } z->parent=y; if ( (y == tree->root) || (0 < TreeCompare(tree, y->key,z->key))) { /* y.key > z.key */ y->left=z; } else { y->right=z; } #ifdef DEBUG_ASSERT Assert(!tree->nil->red,"nil not red in TreeInsertHelp"); #endif }
RBNODE RbExactQuery (RBTREE tree, RBKEY q) { RBNODE x=tree->root->left; RBNODE nil=tree->nil; int compVal; if (x == nil) return(0); compVal= TreeCompare(tree, x->key,(int*) q); while(0 != compVal) {/*assignemnt*/ if (0 < compVal) { /* x->key > q */ x=x->left; } else { x=x->right; } if ( x == nil) return(0); compVal = TreeCompare(tree, x->key,(int*) q); } return(x); }
STKSTACK RbEnumerate (RBTREE tree, RBKEY low, RBKEY high) { STKSTACK enumResultStack=0; RBNODE nil=tree->nil; RBNODE x=tree->root->left; RBNODE lastBest=nil; enumResultStack=StackCreate(); while(nil != x) { if ( 0 < (TreeCompare(tree, x->key, high)) ) { /* x->key > high */ x=x->left; } else { lastBest=x; x=x->right; } } while ( (lastBest != nil) && (0 >= TreeCompare(tree, low,lastBest->key))) { StackPush(enumResultStack,lastBest); lastBest=RbTreePredecessor(tree,lastBest); } return(enumResultStack); }
int RbNext (RBITER rbit, RBKEY * pkey, RBVALUE * pinfo) { RBNODE next = rbit->next; RBNODE nil = rbit->rbtree->nil; if (next == nil) return 0; rbit->next = RbTreeSuccessor(rbit->rbtree, next); if (rbit->high) { if (0 < TreeCompare(rbit->rbtree, next->key, rbit->high)) { /* next->key > rbit->high */ rbit->next = rbit->rbtree->nil; return 0; } } *pkey = next->key; *pinfo = next->info; return 1; }
/*********************************************************************** * FUNCTION: FindLast * * Find highest key in tree no higher than high * ***********************************************************************/ static RBNODE FindLast (RBTREE tree, RBKEY high) { RBNODE nil=tree->nil; RBNODE x=tree->root->left; RBNODE lastBest=nil; /* Find starting location */ while(nil != x) { if ( high && 0 < (TreeCompare(tree, x->key, high)) ) { /* x->key > high */ x=x->left; } else { lastBest=x; x=x->right; } } return lastBest; }
/*********************************************************************** * FUNCTION: FindFirst * * Find lowest key in tree no lower than low * ***********************************************************************/ static RBNODE FindFirst (RBTREE tree, RBKEY low) { RBNODE nil=tree->nil; RBNODE x=tree->root->left; RBNODE lastBest=nil; /* Find starting location */ while(nil != x) { if ( low && 0 > (TreeCompare(tree, x->key, low)) ) { /* x->key < low */ x=x->right; } else { lastBest=x; x=x->left; } } return lastBest; }
int RbTraverseUp (RBTREE tree, RBKEY low, RBKEY high, void *param, TraverseFuncType TraverseFunc) { RBNODE nil=tree->nil; RBNODE lastBest=nil; int rtn=1; /* Find starting location */ lastBest = FindFirst(tree, low); /* Now traverse, watching for ending location */ while ( (lastBest != nil) && (0 <= TreeCompare(tree, high, lastBest->key))) { rtn = (*TraverseFunc)(lastBest->key, lastBest->info, param); if (!rtn) return rtn; lastBest=RbTreeSuccessor(tree,lastBest); } return rtn; }
static void s_TEST_TreeOperations() { typedef CTreeNode<int> TTree; TTree* orig = new TTree(0); TTree* orig10 = orig->AddNode(10); TTree* orig11 = orig->AddNode(11); orig10->AddNode(20); orig10->AddNode(21); orig11->AddNode(22); orig11->AddNode(23); TTree* corr = new TTree(11); corr->AddNode(22); corr->AddNode(23); TTree* corr0 = corr->AddNode(0); TTree* corr10 = corr0->AddNode(10); corr10->AddNode(20); corr10->AddNode(21); TreeReRoot(*orig10); cout << "After rerooting original tree by node 10, " << endl; cout << "the original tree and correct tree are now "; if(TreeCompare(*orig10, *corr, TestFunctor3)) { cout << "the same." << endl; } else { cout << "different." << endl; } cout << endl; TreePrint(cout, *orig10, s_IntToStr, false); TreePrint(cout, *corr, s_IntToStr, false); cout << endl; /* TTree* corr2 = new TTree(11); corr2->AddNode(22); corr2->AddNode(23); corr2->AddNode(0); TTree* t = orig->DetachNode(orig10); cout << "After removing node 10 from this tree, " << endl; cout << "the original tree and correct tree are now "; if(TreeCompare(*orig11, *corr2, TestFunctor3)) { cout << "the same." << endl; } else { cout << "different." << endl; } cout << endl; TreePrint(cout, *orig11, s_IntToStr, false); TreePrint(cout, *t, s_IntToStr, false); TreePrint(cout, *corr2, s_IntToStr, false); cout << endl; */ delete orig->GetRoot(); delete corr->GetRoot(); }
static void s_TEST_Tree() { typedef CTreeNode<int> TTree; TTree* tr = new TTree(0); TTree* tr10 = tr->AddNode(10); tr->AddNode(11); tr10->AddNode(20); tr10->AddNode(21); TTree* sr = new TTree(0); sr->AddNode(10); sr->AddNode(11); TTree* ur = new TTree(0); ur->AddNode(10); ur->AddNode(11); ur->AddNode(20); ur->AddNode(21); // TreePrint(cout, *tr, (IntConvType) NStr::IntToString); // TreeReRoot(*tr10); // TreePrint(cout, *tr10, (IntConvType) NStr::IntToString); cout << "Testing Breadth First Traversal" << endl; TreeBreadthFirstTraverse(*tr, TestFunctor2); cout << endl; cout << "Testing Depth First Traversal" << endl; TreeDepthFirstTraverse(*tr, TestFunctor1); cout << endl; cout << "Testing Tree Comparison" << endl; cout << "tr and tr10 are "; if(!TreeCompare(*tr, *tr10, TestFunctor3)) cout << "not "; cout << "the same." << endl; cout << "tr and tr are "; if(!TreeCompare(*tr, *tr, TestFunctor3)) cout << "not "; cout << "the same." << endl; cout << "tr and sr are "; if(!TreeCompare(*tr, *sr, TestFunctor3)) cout << "not "; cout << "the same." << endl; cout << "tr and ur are "; if(!TreeCompare(*tr, *ur, TestFunctor3)) cout << "not "; cout << "the same." << endl; cout << "sr and ur are "; if(!TreeCompare(*sr, *ur, TestFunctor3)) cout << "not "; cout << "the same." << endl; cout << endl; {{ unsigned int cnt; TTree::TNodeList_CI it = tr->SubNodeBegin(); TTree::TNodeList_CI it_end = tr->SubNodeEnd(); for (cnt = 0; it != it_end; ++it, ++cnt) { const TTree* t = *it; int v = t->GetValue(); assert(v == 10 || v == 11); } assert(cnt == 2); }} {{ TTree* tr2 = new TTree(*tr); unsigned int cnt; TTree::TNodeList_CI it = tr2->SubNodeBegin(); TTree::TNodeList_CI it_end = tr2->SubNodeEnd(); for (cnt = 0; it != it_end; ++it, ++cnt) { const TTree* t = *it; int v = t->GetValue(); assert(v == 10 || v == 11); } assert(cnt == 2); delete tr2; }} {{ TTree::TNodeList_I it = tr->SubNodeBegin(); TTree::TNodeList_I it_end = tr->SubNodeEnd(); for (; it != it_end; ++it) { TTree* t = *it; int v = t->GetValue(); if (v == 10) { tr->RemoveNode(t); break; } } }} TreeDepthFirstTraverse(*tr, TestFunctor1); cout << endl; {{ unsigned int cnt; TTree::TNodeList_CI it = tr->SubNodeBegin(); TTree::TNodeList_CI it_end = tr->SubNodeEnd(); for (cnt = 0; it != it_end; ++it, ++cnt) { const TTree* t = *it; int v = t->GetValue(); assert(v == 11); } assert(cnt == 1); }} delete tr; TTree* str = tr = new TTree(0); // // 0 - 2 // - 4 // - 3 // - 5 // - 6 // TTree* tr4 = tr->AddNode(2)->AddNode(4); tr = tr->AddNode(3); TTree* tr5 = tr->AddNode(5); TTree* tr6 = tr->AddNode(6); cout << "Test Tree: " << endl; TreeDepthFirstTraverse(*str, TestFunctor1); cout << endl; vector<const TTree*> trace_vec; TreeTraceToRoot(*tr6, trace_vec); assert(trace_vec.size() == 3); {{ cout << "Trace to root: "; ITERATE(vector<const TTree*>, it, trace_vec) { cout << (*it)->GetValue() << "; "; } cout << endl; }} const TTree* parent_node = TreeFindCommonParent(*tr4, *tr6); assert(tr4->IsParent(*parent_node)); assert(tr6->IsParent(*parent_node)); assert(!tr4->IsParent(*tr6)); assert(parent_node); cout << "parent: " << parent_node->GetValue() << endl; assert(parent_node->GetValue() == 0); parent_node = TreeFindCommonParent(*tr5, *tr6); assert(parent_node); assert(parent_node->GetValue() == 3); TreePrint(cout, *str, s_IntToStr); cout << endl; TreeReRoot(*tr5); TreePrint(cout, *tr5, s_IntToStr); tr5->MoveSubnodes(str); TreePrint(cout, *tr5, s_IntToStr); delete tr5; delete ur; delete sr; }