rb_red_blk_node* RBEnumerateNext(rb_red_blk_iter *it) { rb_red_blk_tree *tree = it->tree; rb_red_blk_node *nil = tree->nil; if (it->curr != nil) { it->curr = TreeSuccessor(it->tree, it->curr); } else { rb_red_blk_node *x = it->tree->root->left; rb_red_blk_node *best = nil; if (it->low) { while (nil != x) { if (tree->Compare(x->key,it->low)==-1) { // x->key < low x = x->right; } else { best = x; x = x->left; } } } else { while (nil != x) { // searching smallest node best = x; x = x->left; } } it->curr = best; } if (it->high && it->curr!=nil) { if (tree->Compare(it->curr->key,it->high)==1) { // curr->key > high it->curr = nil; } } return it->curr; }
/** * Remove an item from a tree * @param aTree the list to which the item is to be added * @param curnode the list item content itself */ void* TreeRemoveNodeIndex(Tree* aTree, Node* curnode, int index) { Node* redundant = curnode; Node* curchild = NULL; int size = curnode->size; void* content = curnode->content; /* if the node to remove has 0 or 1 children, it can be removed without involving another node */ if (curnode->child[LEFT] && curnode->child[RIGHT]) /* 2 children */ redundant = TreeSuccessor(curnode); /* now redundant must have at most one child */ curchild = redundant->child[(redundant->child[LEFT] != NULL) ? LEFT : RIGHT]; if (curchild) /* we could have no children at all */ curchild->parent = redundant->parent; if (redundant->parent == NULL) aTree->index[index].root = curchild; else { if (redundant == redundant->parent->child[LEFT]) redundant->parent->child[LEFT] = curchild; else redundant->parent->child[RIGHT] = curchild; } if (redundant != curnode) { curnode->content = redundant->content; curnode->size = redundant->size; } if (isBlack(redundant)) { if (curchild == NULL) { if (redundant->parent) { Node temp; memset(&temp, '\0', sizeof(Node)); temp.parent = (redundant) ? redundant->parent : NULL; temp.red = 0; TreeBalanceAfterRemove(aTree, &temp, index); } } else TreeBalanceAfterRemove(aTree, curchild, index); } #if defined(UNIT_TESTS) free(redundant); #else (aTree->heap_tracking) ? myfree(__FILE__, __LINE__, redundant) : free(redundant); #endif if (index == 0) { aTree->size -= size; --(aTree->count); } return content; }
void dumpSet(rb_red_blk_tree* tree){ rb_red_blk_node* i; for(i = tree->first; i != tree->sentinel; i = TreeSuccessor(tree, i)){ dPrintf((SZF " ",*(size_t*)(i->key))); } dPrintf(("\n\n")); }
rb_node* RB::DeleteNode(int data) { rb_node *position = find_node(data); rb_node *y = 0, *x = 0; if (!position) { cout << "Not Found" << endl; return 0; } if (position->left == 0 || position->right == 0) y = position; else y = TreeSuccessor(position); if (!y->left) x = y->right; else if (!y->right) x = y->left; if (!y->parent) root = x; else if (y == y->parent->left) y->parent->left = x; else y->parent->right = x; if (x) x->parent = y->parent; if (position != y) { position->data = y->data; } if (y->color == rb_black) DeleteFixUp(x); return y; }
Node* TreeNextElementIndex(Tree* aTree, Node* curnode, int index) { if (curnode == NULL) curnode = TreeMinimum(aTree->index[index].root); else curnode = TreeSuccessor(curnode); return curnode; }
static HRESULT RBDelete(std_map* self, std_map_node* z) { std_map_node* y; std_map_node* x; std_map_node* nil=self->m_pNil; std_map_node* root=self->m_pRoot; y= ((z->pLeft == nil) || (z->pRight == nil)) ? z : TreeSuccessor(self,z); x= (y->pLeft == nil) ? y->pRight : y->pLeft; if (root == (x->pParent = y->pParent)) { /* assignment of y->p to x->p is intentional */ root->pLeft=x; } else { if (y == y->pParent->pLeft) { y->pParent->pLeft=x; } else { y->pParent->pRight=x; } } if (y != z) { /* y should not be nil in this case */ /* y is the node to splice out and x is its child */ if (!(y->bRed)) RBDeleteFixUp(self,x); KeyDtor(self, z->pKey); DataDtor(self, z->pData); y->pLeft=z->pLeft; y->pRight=z->pRight; y->pParent=z->pParent; y->bRed=z->bRed; z->pLeft->pParent=z->pRight->pParent=y; if (z == z->pParent->pLeft) { z->pParent->pLeft=y; } else { z->pParent->pRight=y; } GaloisFree(z); } else { KeyDtor(self, y->pKey); DataDtor(self, y->pData); if (!(y->bRed)) RBDeleteFixUp(self,x); GaloisFree(y); } return S_OK; }
void RBDelete(rb_red_blk_tree* tree, rb_red_blk_node* z){ rb_red_blk_node* y; rb_red_blk_node* x; rb_red_blk_node* nil=tree->nil; rb_red_blk_node* root=tree->root; y= ((z->left == nil) || (z->right == nil)) ? z : TreeSuccessor(tree,z); x= (y->left == nil) ? y->right : y->left; if (root == (x->parent = y->parent)) { /* assignment of y->p to x->p is intentional */ root->left=x; } else { if (y == y->parent->left) { y->parent->left=x; } else { y->parent->right=x; } } if (y != z) { /* y should not be nil in this case */ #ifdef DEBUG_ASSERT Assert( (y!=tree->nil),"y is nil in RBDelete\n"); #endif /* y is the node to splice out and x is its child */ if (!(y->red)) RBDeleteFixUp(tree,x); tree->DestroyKey(z->key); tree->DestroyInfo(z->info); y->left=z->left; y->right=z->right; y->parent=z->parent; y->red=z->red; z->left->parent=z->right->parent=y; if (z == z->parent->left) { z->parent->left=y; } else { z->parent->right=y; } free(z); } else { tree->DestroyKey(y->key); tree->DestroyInfo(y->info); if (!(y->red)) RBDeleteFixUp(tree,x); free(y); } #ifdef DEBUG_ASSERT Assert(!tree->nil->red,"nil not black in RBDelete"); #endif }
void RBTree::RBDelete(int key) { rb_red_blk_node* y; rb_red_blk_node* x; rb_red_blk_node* nil=tree->nil; rb_red_blk_node* root=tree->root; rb_red_blk_node* z = RBExactQuery(key); if (!z) { return; } y= ((z->left == nil) || (z->right == nil)) ? z : TreeSuccessor(z); /* XXX: original code was : x= (y->left == nil) ? y->right : y->left; */ x= (y->left > nil) ? y->right : y->left; if (root == (x->parent = y->parent)) { root->left=x; } else { if (y == y->parent->left) { y->parent->left=x; } else { y->parent->right=x; } } if (y != z) { if (!(y->red)) RBDeleteFixUp(x); y->left=z->left; y->right=z->right; y->parent=z->parent; y->red=z->red; z->left->parent=z->right->parent=y; if (z == z->parent->left) { z->parent->left=y; } else { z->parent->right=y; } free(z); } else { if (!(y->red)) RBDeleteFixUp(x); free(y); } }
void stepEdges(ActiveEdgeList *ael, const rb_red_blk_tree* activePrims){ static int scanLine; const static Comparator leftToRight = {(CompareF)(&leftToRightF), &scanLine}; LinkN **aelHead = &(ael->activeEdges); scanLine = ++(ael->scanLine); { LinkN *i, *p, *nextP; for(p = NULL, i = ael->activeEdges; i; (p = i),(i = nextP)){ const EdgeListEntry *const entry = i->data; Point **const edge = entry->edge; const float ys = edge[START]->y, ye = edge[END]->y, edgeEnd = max(ys, ye); nextP = i->tail; if(edgeEnd < scanLine){ #ifndef NDEBUG { const char* msg = "Deactivating %s with y-span: %f -> %f with x-span: %f -> %f(true: %f -> %f)\n", *color = fmtColor(entry->owner->color); const float lowEnd = min(ys, ye), mnX = getMinXForLine(entry, scanLine), mxX = getMaxXForLine(entry, scanLine), sX = edge[START]->x, eX = edge[END]->x; dPrintf((msg, color, lowEnd, edgeEnd, mnX, mxX, sX, eX)); } #endif /* Entries don't own the primitives they point to, * so we can get away with a simple free */ freeLink(removeLink(aelHead, i, p), &free); i = p; /* We don't want to advance p into garbage data */ } } } { const rb_red_blk_node *i; for(i = activePrims->first; i != activePrims->sentinel; i = TreeSuccessor(activePrims, i)){ Primitive *const prim = i->key; const size_t jMax = prim->arity; size_t j; for(j = 0; j < jMax; ++j){ Point **const e = prim->boundary + j; const float sy = e[START]->y, ey = e[END]->y, mnY = min(sy, ey), mxY = max(sy, ey); const bool singleton = prim->arity == 1; if((roundOwn(mnY) == scanLine && (!CLOSE_ENOUGH(sy,ey) || (singleton /* newEdge.isSingleton() */))) || (scanLine == 0 && mnY < 0 && mxY > 0)){ LinkN* newEdge = makeLinkEZ(e, prim); #ifndef NDEBUG { const char* msg = "Activating %s with y-span: %f -> %f with x-span: %f -> %f(true: %f -> %f)\n", *color = fmtColor(prim->color); const float mnX = getMinXForLine(newEdge->data, scanLine), mxX = getMaxXForLine(newEdge->data, scanLine), sX = e[START]->x, eX = e[END]->x; dPrintf((msg, color, mnY, mxY, mnX, mxX, sX, eX)); } #endif linkFront(aelHead, newEdge); if (singleton) { dPrintf(("\t->Activating dummy end\n")); linkFront(aelHead, makeLink(e, prim, true)); } } } } } mergeSort(&(ael->activeEdges), &leftToRight); }
int main(int argc, char** argv) { int option=0; int64_t newKey,newKey2; rb_red_blk_node* newNode; rb_red_blk_tree* tree; int64_t* array = 0; int64_t* array2 = 0; unsigned int N = 65536; //total number of elements to insert unsigned int M = 16384; //number of elements to delete from the beginning unsigned int M2 = 16384; //number of elements to delete from the end int i; unsigned int j; time_t t1 = time(0); unsigned int seed = t1; double par = 2.5; for(i=1;i<argc;i++) if(argv[i][0] == '-') switch(argv[i][1]) { case 'N': N = atoi(argv[i+1]); break; case 'M': M = atoi(argv[i+1]); if(i+2 < argc) { if(isdigit(argv[i+2][0])) M2 = atoi(argv[i+2]); else M2 = M; } else M2 = M; break; case 's': seed = atoi(argv[i+1]); break; case 'p': par = atof(argv[i+1]); break; default: fprintf(stderr,"unrecognized parameter: %s!\n",argv[i]); break; } if(M + M2 >= N) { fprintf(stderr,"Error: number of elements to delete (%u + %u) is more than the total number of elements (%u)!\n", M,M2,N); return 1; } tree=RBTreeCreate(CmpInt64,NullFunction,NullFunction,NullFunction,NullFunction,DFInt64,&par); array = SafeMalloc(sizeof(int64_t)*N); for(j=0;j<N;j++) { array[j] = ((int64_t)rand())*((int64_t)rand())*((int64_t)rand()); RBTreeInsert(tree,(void*)(array[j]),0); } for(j=0;j<M;j++) { newNode = RBExactQuery(tree,(void*)(array[j])); if(!newNode) { fprintf(stderr,"Error: node not found!\n"); goto rbt_end; } RBDelete(tree,newNode); } for(j=N-M2;j<N;j++) { newNode = RBExactQuery(tree,(void*)(array[j])); if(!newNode) { fprintf(stderr,"Error: node not found!\n"); goto rbt_end; } RBDelete(tree,newNode); } N = N-M2-M; array2 = array+M; quicksort(array2,0,N); j=0; newNode = TreeFirst(tree); double cdf = 0.0; do { int64_t v1 = (int64_t)(newNode->key); if(v1 != array2[j]) { fprintf(stderr,"error: %d != %d!\n",v1,array2[j]); break; } double cdf2 = GetNodeRank(tree,newNode); double diff = fabs(cdf2-cdf); if(diff > EPSILON) { fprintf(stderr,"wrong cdf value: %g != %g (diff: %g)!\n",cdf,cdf2,diff); break; } j++; cdf += DFInt64((void*)array2[j],&par); newNode = TreeSuccessor(tree,newNode); } while(newNode != tree->nil && j<N); if( !(newNode == tree->nil && j == N) ) { fprintf(stderr,"error: tree or array too short / long!\n"); } rbt_end: RBTreeDestroy(tree); free(array); time_t t2 = time(0); fprintf(stderr,"runtime: %u\n",(unsigned int)(t2-t1)); return 0; }
void render(PaletteRef *raster, int lineWidth, int numLines, const rb_red_blk_tree *scanLinePrimBuckets){ static OntoProj screenPlaneData = {offsetof(Point, z), 0}; static const Transformation screenPlane = {(TransformationF)(&snapOntoProj), &screenPlaneData}; { int line; rb_red_blk_tree activePrimSet; ActiveEdgeList ael = freshAEL(); rb_red_blk_map_tree inFlags; rb_red_blk_tree deFlags; /* This ensures that both trees are initialized and in a cleared state */ RBTreeMapInit(&inFlags, pointerDiffF, NULL, &RBMapNodeAlloc, NULL); RBTreeInit(&deFlags, pointerDiffF, NULL, &RBNodeAlloc); RBTreeInit(&activePrimSet, pointerDiffF, NULL, &RBNodeAlloc); dPrintf(("Scanning line: 0\n")); for(line = 0; line < numLines; (++line), (raster += lineWidth)) { rb_red_blk_node *primIt, *p = NULL, *nextP; dPrintf(("\tUpdating activePrimSet\n")); for (primIt = activePrimSet.first; primIt != activePrimSet.sentinel; (p = primIt), (primIt = nextP)) { const Primitive* prim = primIt->key; const int top = roundOwn(topMostPoint(prim)); nextP = TreeSuccessor(&activePrimSet, primIt); if(top < line){ #ifndef NDEBUG { const int bottom = roundOwn(bottomMostPoint(prim)); dPrintf(("\t\t%d -> %d ( %s ) is not valid here: %d\n",top,bottom,fmtColor(prim->color), line)); } #endif RBDelete(&activePrimSet, primIt); primIt = p; /* We don't want to advance p into garbage data */ } } { const rb_red_blk_tree *bucket = scanLinePrimBuckets + line; const rb_red_blk_node *node; for(node = bucket->first; node != bucket->sentinel; node = TreeSuccessor(bucket, node)) { Primitive * prim = node->key; #ifndef NDEBUG { const int top = roundOwn(topMostPoint(prim)), bottom = roundOwn(bottomMostPoint(prim)); dPrintf(("\t\t%d -> %d ( %s ) is added here: %d\n",top,bottom,fmtColor(prim->color), line)); } #endif RBTreeInsert(&activePrimSet, prim); } } stepEdges(&ael, &activePrimSet); { int curPixel = 0; const Primitive *curDraw = NULL; EdgeListEntry *nextEdge; LinkN* i = ael.activeEdges; if(i){ nextEdge = i->data; while(nextEdge && curPixel < lineWidth){ EdgeListEntry *const startEdge = nextEdge; Primitive *const startOwner = startEdge->owner; int startX = roundOwn(getSmartXForLine(startEdge, line)), nextX; rb_red_blk_map_node *inFlag = (rb_red_blk_map_node *)RBExactQuery((rb_red_blk_tree*)(&inFlags), startOwner); if(inFlag){ static Point localPoints[6]; /* We don't recurse, so this is fine */ static Edge flatHere = {localPoints, localPoints + 1}, flatIn = {localPoints + 2, localPoints + 3}, vert = {localPoints + 4, localPoints + 5}; const EdgeListEntry *const edgeInEntry = inFlag->info; Point **const edgeHere = startEdge->edge, **edgeIn = edgeInEntry->edge; const Point *const s = edgeHere[START], *const e = edgeHere[END]; Point here; bool sV, eV, v; float dotH, dotIn; transformEdge(&screenPlane, edgeHere, flatHere); transformEdge(&screenPlane, edgeIn, flatIn); INIT_POINT(here, startX, line, 0); sV = contains(edgeIn, s); eV = contains(edgeIn, e); v = (sV || eV) && contains(flatIn, &here) && contains(flatHere, &here) && (startOwner->arity != 1); vert[START] = &here; INIT_POINT(*(vert[END]), startX, line+1, 0); dotH = v ? dotEdge(vert, flatHere) : 0; dotIn = v ? dotEdge(vert, flatIn) : 0; if(!v || dotH * dotIn > 0){ dPrintf(("\tNot *in* old %s at %f\n", fmtColor(startEdge->owner->color), getSmartXForLine(startEdge, line))); RBSetAdd(&deFlags, startOwner); } else { dPrintf(("\tFound horizontal vertex %s at %f. Don't delete it yet\n",fmtColor(startEdge->owner->color), getSmartXForLine(startEdge, line))); } } else { dPrintf(("\tNow *in* new %s at %f\n",fmtColor(startEdge->owner->color), getSmartXForLine(startEdge, line))); /* This might happen if a polygon is parallel to the x-axis */ RBMapPut(&inFlags, startOwner, startEdge); } if(curPixel < startX){ dPrintf(("\tcurPixel has fallen behind, dragging from %d to %d\n",curPixel, startX)); curPixel = startX; } i = i->tail; if(i){ nextEdge = i->data; nextX = roundOwn(getSmartXForLine(nextEdge, line)); dPrintf(("\tNext edges @ x = %d from %s\n",nextX, fmtColor(nextEdge->owner->color))); } else { dPrintf(("\tNo more edges\n")); nextEdge = NULL; nextX = 0; } nextX = min(nextX, lineWidth); while ((!nextEdge && curPixel < lineWidth) || (curPixel < nextX)) { bool zFight = false, solitary = false; float bestZ = HUGE_VAL; const rb_red_blk_node *node; curDraw = NULL; dPrintf(("\tTesting depth:\n")); for(node = inFlags.tree.first; node != inFlags.tree.sentinel; node = TreeSuccessor((rb_red_blk_tree*)(&inFlags), node)) { const Primitive *prim = node->key; /* We need sub-pixel accuracy */ const float testZ = getZForXY(prim, curPixel, line); if(testZ <= bestZ + PT_EPS){ dPrintf(("\t\tHit: %f <= %f for %s\n",testZ, bestZ, fmtColor(prim->color))); if (CLOSE_ENOUGH(testZ, bestZ)) { if (prim->arity == 1) { zFight = curDraw && curDraw->arity == 1; curDraw = prim; solitary = RBSetContains(&deFlags, prim); } else { zFight = curDraw && curDraw->arity != 1; } } else { zFight = false; bestZ = testZ; curDraw = prim; solitary = RBSetContains(&deFlags, prim); } } else { dPrintf(("\t\tMiss: %f > %f for %s\n",testZ, bestZ, fmtColor(prim->color))); } } if(curDraw){ #ifndef NDEBUG if(nextEdge || solitary){ #endif const int drawWidth = (zFight || solitary) ? 1 : ((nextEdge ? nextX : lineWidth) - curPixel), stopPixel = curPixel + min(lineWidth - curPixel, max(0, drawWidth)); const PaletteRef drawColor = /*(uint16_t)roundOwn(63 * bestZ / 100) << 5;*/decodeColor(curDraw->color); dPrintf(("Drawing %d @ (%d, %d)\n",drawWidth,curPixel,line)); dPrintf(("Drawing %d @ (%d, %d)\n",stopPixel - curPixel,curPixel,line)); while(curPixel < stopPixel){ raster[curPixel++] = drawColor; } #ifndef NDEBUG } else { dPrintf(("Warning: we probably shouldn't have to draw if there are no more edges to turn us off. Look for parity errors\n"); RBTreeClear((rb_red_blk_tree*)&inFlags)); } #endif } else if(!inFlags.tree.size && nextEdge){ /* fast forward, we aren't in any polys */ dPrintf(("Not in any polys at the moment, fast-forwarding(1) to %d\n", nextX)); curPixel = nextX; } else { /* Nothing left */ dPrintf(("Nothing to draw at end of line\n")); curPixel = lineWidth; } for(node = deFlags.first; node != deFlags.sentinel; node = TreeSuccessor(&deFlags, node)){ RBMapRemove(&inFlags, node->key); } RBTreeClear(&deFlags); } if (!inFlags.tree.size && nextEdge) { dPrintf(("Not in any polys at the moment, fast-forwarding(2) to %d\n", nextX)); curPixel = nextX; } } } } #ifndef NDEBUG { dPrintf(("Scanning line: %d\n", line+1)); if(inFlags.tree.size){ rb_red_blk_node *node; dPrintf(("\tGarbage left in inFlags:\n")); for (node = inFlags.tree.first; node != inFlags.tree.sentinel; node = TreeSuccessor((rb_red_blk_tree*)&inFlags, node)) { dPrintf(("\t\t%s\n",fmtColor(((const Primitive*)node->key)->color))); } } } #endif RBTreeClear(&deFlags); RBTreeClear((rb_red_blk_tree*)(&inFlags)); } RBTreeDestroy(&activePrimSet, false); RBTreeDestroy(&deFlags, false); RBTreeDestroy((rb_red_blk_tree*)(&inFlags), false); }
int main() { stk_stack* enumResult; int option=0; int newKey,newKey2; int* newInt; rb_red_blk_node* newNode; rb_red_blk_tree* tree; tree=RBTreeCreate(IntComp,IntDest,InfoDest,IntPrint,InfoPrint); while(option!=8) { printf("choose one of the following:\n"); printf("(1) add to tree\n(2) delete from tree\n(3) query\n"); printf("(4) find predecessor\n(5) find sucessor\n(6) enumerate\n"); printf("(7) print tree\n(8) quit\n"); do option=fgetc(stdin); while(-1 != option && isspace(option)); option-='0'; switch(option) { case 1: { printf("type key for new node\n"); scanf("%i",&newKey); newInt=(int*) malloc(sizeof(int)); *newInt=newKey; RBTreeInsert(tree,newInt,0); } break; case 2: { printf("type key of node to remove\n"); scanf("%i",&newKey); if ( ( newNode=RBExactQuery(tree,&newKey ) ) ) RBDelete(tree,newNode);/*assignment*/ else printf("key not found in tree, no action taken\n"); } break; case 3: { printf("type key of node to query for\n"); scanf("%i",&newKey); if ( ( newNode = RBExactQuery(tree,&newKey) ) ) {/*assignment*/ printf("data found in tree at location %i\n",(int)newNode); } else { printf("data not in tree\n"); } } break; case 4: { printf("type key of node to find predecessor of\n"); scanf("%i",&newKey); if ( ( newNode = RBExactQuery(tree,&newKey) ) ) {/*assignment*/ newNode=TreePredecessor(tree,newNode); if(tree->nil == newNode) { printf("there is no predecessor for that node (it is a minimum)\n"); } else { printf("predecessor has key %i\n",*(int*)newNode->key); } } else { printf("data not in tree\n"); } } break; case 5: { printf("type key of node to find successor of\n"); scanf("%i",&newKey); if ( (newNode = RBExactQuery(tree,&newKey) ) ) { newNode=TreeSuccessor(tree,newNode); if(tree->nil == newNode) { printf("there is no successor for that node (it is a maximum)\n"); } else { printf("successor has key %i\n",*(int*)newNode->key); } } else { printf("data not in tree\n"); } } break; case 6: { printf("type low and high keys to see all keys between them\n"); scanf("%i %i",&newKey,&newKey2); enumResult=RBEnumerate(tree,&newKey,&newKey2); while ( (newNode = StackPop(enumResult)) ) { tree->PrintKey(newNode->key); printf("\n"); } free(enumResult); } break; case 7: { RBTreePrint(tree); } break; case 8: { RBTreeDestroy(tree); return 0; } break; default: printf("Invalid input; Please try again.\n"); } } return 0; }
main () { tree_sTable *tp; sNode *np; int key; int i; char s[256]; char *cp; char c; tp = tree_CreateTable(sizeof(int), offsetof(sNode, key), sizeof(sNode), 100, tree_eComp_int32, NULL); for (i = 0; i < 1000; i += 10) { tree_Insert(tp, &i); } for ( ;;) { printf("Command: "); cp = gets(s); c = s[0]; if (cp == NULL || c == '\0') { printf("\nGoodbye\n"); return; } switch (c) { case 'i': case 'I': printf("Insert, Key: "); gets(s); key = atoi(s); if (tree_Find(tp, &key) == NULL) { tree_Insert(tp, &key); } else printf("\nKey allready exists!\n"); break; case 'd': case 'D': printf("Delete, Key: "); gets(s); key = atoi(s); if ((np = tree_Find(tp, &key)) != NULL) { tree_Remove(tp, &key); } else printf("\nKey does not exist!\n"); break; case 'f': case 'F': printf("Find, Key: "); gets(s); key = atoi(s); if ((np = tree_Find(tp, &key)) == NULL) { printf("\nKey does not exist!\n"); } else printf("\nKey exists! %d\n", np->key); break; case 's': case 'S': printf("Find successor, Key: "); gets(s); key = atoi(s); if ((np = tree_FindSuccessor(tp, &key)) == NULL) { printf("\nKey does not exist!\n"); } else printf("\nKey exists! %d\n", np->key); break; case 'p': case 'P': printf("Find predecessor, Key: "); gets(s); key = atoi(s); if ((np = tree_FindPredecessor(tp, &key)) == NULL) { printf("\nKey does not exist!\n"); } else printf("\nKey exists! %d\n", np->key); break; #if 0 case 't': case 'T': printf("Start: "); gets(s); start = atoi(s); printf("Stop: "); gets(s); stop = atoi(s); printf("Order: "); gets(s); c = s[0]; switch (c) { case 's': case 'S': printf("\navl-tree\n"); i = start; j = stop; sts = sys$getjpiw(0, &pid, 0,item_list, 0, 0, 0); cpu = cputim; page = pageflts; for (; i <= j; i++) { if (TreeSearch(tp,i) == tp->Null) { np = TreeAlloc(tp, i); TreeInsert(tp, np); } } sts = sys$getjpiw(0, &pid, 0,item_list, 0, 0, 0); printf("Cputim: %d, Pageflts: %d\n", cputim - cpu, pageflts - page); i = start; j = stop; printf("\nlib$tree\n"); sts = sys$getjpiw(0, &pid, 0,item_list, 0, 0, 0); cpu = cputim; page = pageflts; for (; i <= j; i++) { sts = lib$lookup_tree(<p, i, Compare, &lnp); if (!(sts & 1)) { lib$insert_tree(<p, i, &0, Compare, Alloc, &lnp, 0); } } sts = sys$getjpiw(0, &pid, 0,item_list, 0, 0, 0); printf("Cputim: %d, Pageflts: %d\n", cputim - cpu, pageflts - page); break; case 'd': case 'D': i = start; j = stop; sts = sys$getjpiw(0, &pid, 0,item_list, 0, 0, 0); cpu = cputim; page = pageflts; for (; i <= j; i++) { if ((np = TreeSearch(tp,i)) != tp->Null) { TreeDelete(tp, np); } else { printf("Could not find %d\n", i); } } sts = sys$getjpiw(0, &pid, 0,item_list, 0, 0, 0); printf("Cputim: %d, Pageflts: %d\n", cputim - cpu, pageflts - page); break; case 'f': case 'F': printf("\navl-tree\n"); i = start; j = stop; sts = sys$getjpiw(0, &pid, 0,item_list, 0, 0, 0); cpu = cputim; page = pageflts; for (; i <= j; i++) { if ((np = TreeSearch(tp,i)) != tp->Null) { } else { printf("Could not find %d\n", i); } } sts = sys$getjpiw(0, &pid, 0,item_list, 0, 0, 0); printf("Cputim: %d, Pageflts: %d\n", cputim - cpu, pageflts - page); i = start; j = stop; printf("\nlib$tree\n"); sts = sys$getjpiw(0, &pid, 0,item_list, 0, 0, 0); cpu = cputim; page = pageflts; for (; i <= j; i++) { sts = lib$lookup_tree(<p, i, Compare, &lnp); } sts = sys$getjpiw(0, &pid, 0,item_list, 0, 0, 0); printf("Cputim: %d, Pageflts: %d\n", cputim - cpu, pageflts - page); break; case 'b': case 'B': i = start; j = stop; sts = sys$getjpiw(0, &pid, 0,item_list, 0, 0, 0); cpu = cputim; page = pageflts; for (; i <= j; j--) { if (TreeSearch(tp,j) == tp->Null) { np = TreeAlloc(tp, j); TreeInsert(tp, np); } } sts = sys$getjpiw(0, &pid, 0,item_list, 0, 0, 0); printf("Cputim: %d, Pageflts: %d\n", cputim - cpu, pageflts - page); break; case 'r': case 'R': i = start; j = stop; sts = sys$getjpiw(0, &pid, 0,item_list, 0, 0, 0); cpu = cputim; page = pageflts; for (; i <= j; i++) { k = 65535 & rand(); if (TreeSearch(tp,k) == tp->Null) { np = TreeAlloc(tp, k); TreeInsert(tp, np); } } sts = sys$getjpiw(0, &pid, 0,item_list, 0, 0, 0); printf("Cputim: %d, Pageflts: %d\n", cputim - cpu, pageflts - page); break; default: printf("Illegal order!\n"); break; } break; case 'p': case 'P': tp->ErrorCount = 0; tp->HZCount = 0; tp->HNCount = 0; tp->HPCount = 0; maxlevel = 0; count = 0; hight = 0; TreePrint(tp, tp->Root, NULL, NULL,0); TreeCheck (tp, tp->Root, &count, &maxlevel, &hight, 0); printf("Hight: %d\n", hight); #if 0 TreePrintInorder(tp, tp->Root, 0); #endif sp = TreeMinimum(tp, tp->Root); ep = TreeMaximum(tp, tp->Root); op = sp; for (np = TreeSuccessor(tp, op); op != ep; np = TreeSuccessor(tp, np)) { #if 0 printf("Key: %d\n", op->Key); #endif if (op->Key >= np->Key) tp->ErrorCount++; op = np; } printf("Hight.......: %d\n", hight); printf("Insert......: %d\n", tp->Insert); printf("Search......: %d\n", tp->Search); printf("Delete......: %d\n", tp->Delete); printf("NodeCount...: %d\n", tp->NodeCount); printf("FreeCount...: %d\n", tp->FreeCount); printf("MaxDepth....: %d\n", tp->MaxDepth); printf("HZCount.....: %d\n", tp->HZCount); printf("HNCount.....: %d\n", tp->HNCount); printf("HPCount.....: %d\n", tp->HPCount); printf("LLCount.....: %d\n", tp->LLCount); printf("LRCount.....: %d\n", tp->LRCount); printf("RLCount.....: %d\n", tp->RLCount); printf("RRCount.....: %d\n", tp->RRCount); printf("AllocCount..: %d\n", tp->AllocCount); printf("MallocCount.: %d\n", tp->MallocCount); printf("ErrorCount..: %d\n", tp->ErrorCount); count = maxlevel = 0; Print(ltp, &count, &maxlevel, 0); printf("\nlib$tree\n"); printf("Count.......: %d\n", count); printf("MaxDepth....: %d\n", maxlevel); break; case 'l': case 'L': TreePrintInorder(tp, tp->Root, 0); break; #endif case 'q': case 'Q': printf("\nGoodbye\n"); return; break; default: printf("Illegal command!\n"); break; } } }