Exemple #1
0
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;
}
Exemple #2
0
/**
 * 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;
}
Exemple #3
0
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"));
}
Exemple #4
0
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;
}
Exemple #5
0
Node* TreeNextElementIndex(Tree* aTree, Node* curnode, int index)
{
	if (curnode == NULL)
		curnode = TreeMinimum(aTree->index[index].root);
	else
		curnode = TreeSuccessor(curnode);
	return curnode;
}
Exemple #6
0
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;
}
Exemple #7
0
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
}
Exemple #8
0
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);
  }
  
}
Exemple #9
0
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);
}
Exemple #10
0
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;
}
Exemple #13
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(&ltp, i, Compare, &lnp);
                    if (!(sts & 1)) {
                        lib$insert_tree(&ltp, 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(&ltp, 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;
        }
    }
}