Пример #1
0
int transpose_onerank(Agraph_t* g, int r, boolean reverse)
{
	int     i,c0,c1,rv;
	node_t  *v,*w;

	rv = 0;
	GD_rank(g)[r].candidate = FALSE;
	for (i = leftmost(g,r); i < rightmost(g,r); i++) {
		v = GD_rank(g)[r].v[i];
		w = GD_rank(g)[r].v[i+1];
		assert (ND_order(v) < ND_order(w));
		if (left2right(g,v,w)) continue;
		c0 = c1 = 0;
		if (r > GD_minrank(g)) {
			c0 += in_cross(v,w);
			c1 += in_cross(w,v);
		}
		if (r < GD_maxrank(g)) {
			c0 += out_cross(v,w);
			c1 += out_cross(w,v);
		}
		if ((c1 < c0) || ((c0 > 0) && reverse && (c1 == c0))) {
			exchange(g,v,w);
			rv += (c0 - c1);
		}
	}
	return rv;
}
Пример #2
0
FLEXT_TEMPIMPL(void TableAnyMap)::iterator::forward()
{ 
    FLEXT_ASSERT(map || ix >= map->n);
	
	if(++ix >= map->n) {
		TableAnyMap *nmap;

		// we reached the end of the slots
		if(map->right) {
			// climb up one
			map = map->right;
			leftmost();
			ix = 0;
		}
		else {
			// fall back
			for(;;) {
				nmap = map->parent;
				if(!nmap) break; // no parent
				if(nmap->left == map) {
					// ok, we are in front of the slots now
					ix = 0;
					map = nmap;
					break;
				}
				else {
					FLEXT_ASSERT(nmap->right == map);
					ix = (map = nmap)->n;
				}
			}
		}
	}
}
Пример #3
0
        void SplayTree::insert(node* n)
        {
            if (unlikely(header.parent == NULL))  // First element.
            {
                header.parent = header.child[LEFT] = header.child[RIGHT] = n;
                n->parent = n->child[LEFT] = n->child[RIGHT] = NULL;
            }
            else // Not first element.
            {
                // Find place to insert node and insert it.
                node* insert_location = header.parent;
                __find(insert_location, n);
                __insert(insert_location, n);

                // Fix up header nodes.
                header.child[LEFT] = leftmost(header.child[LEFT]);
                header.child[RIGHT] = rightmost(header.child[RIGHT]);

                // Splay new node.
                splay(n);
            }

            // Increment size count.
            (header_n()->data)++;
        }
Пример #4
0
/*
 * defines ND_sortweight of each node in r0 w.r.t. r1
 * returns...
 */
static boolean medians(Agraph_t *g, int r0, int r1)
{
	static int *list;
	static int list_extent;
	int     i,j,lm,rm,lspan,rspan;
	node_t  *n,**v;
	edge_t  *e;
	boolean hasfixed = FALSE;

	if (list_extent < GD_maxinoutdeg(g->root)) {
		list_extent = GD_maxinoutdeg(g->root);
		if (!list) list = realloc(list,sizeof(list[0])*list_extent);
		else list = realloc(list,sizeof(list[0])*list_extent);
	}
	v = GD_rank(g)[r0].v;
	for (i = leftmost(g,r0); i <= rightmost(g,r0); i++) {
		n = v[i]; j = 0;
		if (r1 > r0) for (e = agfstout(g,n); e; e = agnxtout(g,e))
			{if (ED_xpenalty(e) > 0) list[j++] = VAL(e->head,ED_headport(e));}
		else for (e = agfstin(g,n); e; e = agnxtin(g,e))
			{if (ED_xpenalty(e) > 0) list[j++] = VAL(e->tail,ED_tailport(e));}
		switch(j) {
			case 0:
				ND_sortweight(n) = -1;		/* no neighbor - median undefined */
				break;
			case 1:
				ND_sortweight(n) = list[0];
				break;
			case 2:
				ND_sortweight(n) = (list[0] + list[1])/2;
				break;
			default:
				qsort(list,j,sizeof(int),int_cmpf);
				if (j % 2) ND_sortweight(n) = list[j/2];
				else {
					/* weighted median */
					rm = j/2;
					lm = rm - 1;
					rspan = list[j-1] - list[rm];
					lspan = list[lm] - list[0];
					if (lspan == rspan)
						ND_sortweight(n) = (list[lm] + list[rm])/2;
					else {
						int w = list[lm]*rspan + list[rm]*lspan;
						ND_sortweight(n) = w / (lspan + rspan);
					}
				}
		}
	}
#ifdef NOTDEF
	/* this code was in the old mincross */
	for (i = 0; i < GD_rank(g)[r0].n; i++) {
		n = v[i];
		if ((ND_out(n).size == 0) && (ND_in(n).size == 0))
			hasfixed |= flat_sortweight(n);
	}
#endif
	return hasfixed;
}
Пример #5
0
/* Returns the next node of N.  NULL iff n is the maximum. */
static Node *next_node(Node *n)
{
    if (n->right) return leftmost(n->right);
    while (n->parent) {
        if (LEFTP(n)) return n->parent;
        n = n->parent;
    }
    return NULL;
}
Пример #6
0
static void reorder(graph_t *g, int r, boolean reverse, boolean hasfixed)
{
	boolean changed, muststay;
	node_t  **vlist, **lp, **rp, **ep;
	int			i;

	changed = FALSE;
	vlist = GD_rank(g)[r].v;
	ep = &vlist[rightmost(g,r)];
	
	for (i = leftmost(g,r); i <= rightmost(g,r); i++) {
		lp = &vlist[leftmost(g,r)];
		/* find leftmost node that can be compared */
		while ((lp < ep) && (ND_sortweight(*lp) < 0)) lp++;
		if (lp >= ep) break;
		/* find the node that can be compared */
		muststay = FALSE;
		for (rp = lp + 1; rp < ep; rp++) {
			if (left2right(g,*lp,*rp)) { muststay = TRUE; break; }
			if (ND_sortweight(*rp) >= 0) break;	/* weight defined; it's comparable */
		}
		if (rp >= ep) break;
		if (muststay == FALSE) {
			register int    p1 = ND_sortweight(*lp);
			register int    p2 = ND_sortweight(*rp);
			if ((p1 > p2) || ((p1 == p2) && (reverse))) {
				exchange(g,*lp,*rp);
				changed = TRUE;
			}
		}
		lp = rp;
		if ((hasfixed == FALSE) && (reverse == FALSE)) ep--;
	}
                                                                                
	if (changed) {
		GD_rank(g)[r].changed = TRUE;
		GD_rank(g)[r].crossing_cache.valid = FALSE;
		if (r > 0) GD_rank(g)[r-1].crossing_cache.valid = FALSE;
		if (r + 1 > GD_rank(g)[r+1].n) GD_rank(g)[r-1].crossing_cache.valid = FALSE;
	}
}
Пример #7
0
static Node *core_bound(ScmTreeCore *tc, ScmTreeCoreBoundOp op, int pop)
{
    Node *root = ROOT(tc);
    if (root) {
        Node *n = (op == SCM_TREE_CORE_MIN)? leftmost(root) : rightmost(root);
        if (pop) {
            n = delete_node(tc, n);
            tc->num_entries--;
        }
        return n;
    } else {
        return NULL;
    }
}
Пример #8
0
static void presort(Agraph_t *ug)
{
	int		r;
	int		i;
	Agraph_t	*mg;

	if (ug == ug->root) return;
	mg = GD_model(ug);
	for (r = GD_minrank(mg); r <= GD_maxrank(mg); r++) {
		qsort(GD_rank(mg)[r].v,GD_rank(mg)[r].n,sizeof(Agnode_t*),presort_cmpf);
		for (i = leftmost(mg,r); i < rightmost(mg,r); i++)
			ND_order(GD_rank(mg)[r].v[i]) = i;
	}
}
Пример #9
0
const RbTreeNode *RbTreeUtil::next(const RbTreeNode *node)
{
    BSLS_ASSERT(node);

    if (node->rightChild()) {
        return leftmost(node->rightChild());                          // RETURN
    }
    const RbTreeNode *parent = node->parent();
    while (node != parent->leftChild()) {
        node   = parent;
        parent = node->parent();
    }

    return parent;
}
Пример #10
0
LIBUXRE_STATIC int
libuxre_regdfaexec(Dfa *dp, Exec *xp)
{
	const unsigned char *s;
	int i, nst, st, mb_cur_max;
	w_type wc;

	dp->flags = xp->flags & REG_NOTEOL;	/* for regtrans() */
	mb_cur_max = xp->mb_cur_max;
	if (xp->nmatch != 0)
		return leftmost(dp, xp);
	if (mb_cur_max == 1 && (xp->flags & REG_NEWLINE) == 0)
		return regdfaexec_opt(dp, xp);
	s = xp->str;
	st = dp->anybol;
	if (xp->flags & REG_NOTBOL)
		st = 1;
	if (dp->acc[st] && (xp->flags & REG_NONEMPTY) == 0)
		return 0;	/* initial empty match allowed */
	for (;;)
	{
		if ((wc = *s++) == '\n')
		{
			if (xp->flags & REG_NEWLINE)
				wc = ROP_EOL;
		}
		else if (!ISONEBYTE(wc) && (i = libuxre_mb2wc(&wc, s)) > 0)
			s += i;
		if ((wc & ~(long)(NCHAR - 1)) != 0
			|| (nst = dp->trans[st][wc]) == 0)
		{
			if ((nst=regtrans(dp, st, wc, mb_cur_max)) == 0)
				return REG_ESPACE;
			if (wc == ROP_EOL) /* REG_NEWLINE only */
			{
				if (dp->acc[nst - 1])
					return 0;
				if (dp->acc[st = dp->anybol])
					return 0;
				continue;
			}
		}
		if (dp->acc[st = nst - 1])
			return 0;
		if (wc == '\0')	/* st == 0 */
			return REG_NOMATCH;
	}
}
Пример #11
0
        const SplayTree::node* SplayTree::successor(const node* n) const
        {
            // If right child, predecessor is just the smallest of the right
            // subtree.
            if (likely(NULL != n->child[RIGHT]))
            {
                return leftmost(n->child[RIGHT]);
            }

            // Else, need to work up the tree to find successor.
            const node* y = n->parent;
            while ((NULL != y) && (n == y->child[RIGHT]))
            {
                n = y;
                y = y->parent;
            }

            return y;
        }
Пример #12
0
MapvNodeBase * MapvBase::unbalancing_removal( MapvNodeBase ** n )
{
  MapvNodeBase * t = *n ;

  while ( t != header() && t->parent ) {
    if      ( t->left  ) { t = t->left ; }
    else if ( t->right ) { t = t->right ; }
    else { // Move to parent and remove this leaf
      *n = t->parent ; t->parent = 0 ;
      if ( (*n)->left == t ) (*n)->left  = 0 ;
      else                   (*n)->right = 0 ;
    }
  }

  if ( t == header() ) {

    header()->parent = 0 ;
    header()->left   = 0 ;
    header()->right  = 0 ;
    header()->color  = red ;  /* Color the header node red */

    Count = 0 ;

    left_end.parent = 0 ;
    left_end.left   = 0 ;
    left_end.right  = 0 ;
    left_end.color  = black ;

    right_end.parent = 0 ;
    right_end.left   = 0 ;
    right_end.right  = 0 ;
    right_end.color  = black ;

    leftmost(  header()->left  = nREnd() ); // left end of the tree
    rightmost( header()->right = nEnd() );  // right end of the tree

    t = 0 ;
  }

  return t ;
}
Пример #13
0
	iterator begin()
	{
		return leftmost();
	}
Пример #14
0
void RbTreeUtil::remove(RbTreeAnchor *tree, RbTreeNode *node)
{
    BSLS_ASSERT(0 != node);
    BSLS_ASSERT(0 != tree);
    BSLS_ASSERT(0 != tree->rootNode());

    RbTreeNode *x, *y;
    RbTreeNode *parentOfX;
    bool        yIsBlackFlag;

    // Implementation Note:  This implementation has been adjusted from the
    // one described in "Introduction to Algorithms" [Cormen, Leiserson,
    // Rivest] (i.e., CLR) to avoid swapping node values (swapping nodes is
    // potentially inefficient and inappropriate for an STL map).
    // Specifically, int case where 'node' has two (non-null) children, CLR
    // (confusingly) swaps the value of the node with its replacement; instead
    // we move node's successor to the position of node, and then recolor its
    // value with the same result).

    // Case 1: If either child of the node being removed is 0, then 'node' can
    // be replaced by its non-null child (or by a null child if 'node' has no
    // children).

    if (0 == node->leftChild()) {
        y = node;
        x = node->rightChild();
    }
    else if (0 == node->rightChild()) {
        y = node;
        x = node->leftChild();
    }
    else {
        // Case 2: Otherwise the 'node' will be replaced by its successor in
        // the tree.

        y = leftmost(node->rightChild());
        x = y->rightChild();
    }
    yIsBlackFlag = y->isBlack();

    if (y == node) {
        // We should be in case 1, where 'node' has (at least 1) null child,
        // and will simply be replaced by one of its children.  In this
        // context, 'x' refers to the node that will replace 'node'.  Simply
        // point the parent of 'node' to its new child, 'x'.  Note that in
        // this context, we may have to set the first and last node of the
        // tree.

        BSLS_ASSERT_SAFE(0 == node->leftChild() || 0 == node->rightChild());
        if (isLeftChild(node)) {
            // If the node being removed is to the left of its parent, it may
            // be the first node of the tree.

            if (node == tree->firstNode()) {
                tree->setFirstNode(next(node));
            }
            node->parent()->setLeftChild(x);
        }
        else {
            node->parent()->setRightChild(x);
        }

        parentOfX = node->parent();
        if (x) {
            x->setParent(node->parent());
        }
    }
    else {
        // We should be in case 2, where 'node' has two non-null children.  In
        // this context 'y' is the successor to 'node' which will be used to
        // replace 'node'.  Note that in this context, we never need to set
        // the first or last node of the tree (as the node being removed has
        // two children).

        BSLS_ASSERT_SAFE(0 != node->leftChild() && 0 != node->rightChild());
        BSLS_ASSERT_SAFE(0 == y->leftChild());
        BSLS_ASSERT_SAFE(x == y->rightChild());

        if (isLeftChild(node)) {
            node->parent()->setLeftChild(y);
        }
        else {
            node->parent()->setRightChild(y);
        }
        y->setLeftChild(node->leftChild());
        y->leftChild()->setParent(y);

        if (y->parent() != node) {
            // The following logic only applies if the replacement node 'y' is
            // not a direct descendent of the 'node' being replaced, otherwise
            // it is a degenerate case.

            BSLS_ASSERT_SAFE(y->parent()->leftChild() == y);

            parentOfX = y->parent();
            y->parent()->setLeftChild(x);  // 'x' is y->rightChild()
            if (x) {
                x->setParent(y->parent());
            }

            y->setRightChild(node->rightChild());
            y->rightChild()->setParent(y);
        }
        else {
            parentOfX = y;
        }
        y->setParent(node->parent());
        y->setColor(node->color());
    }

    if (yIsBlackFlag) {
        recolorTreeAfterRemoval(tree, x, parentOfX);
    }
    BSLS_ASSERT(!tree->rootNode() ||
                tree->sentinel() == tree->rootNode()->parent());
    tree->decrementNumNodes();
}
Пример #15
0
void MapvBase::remove( MapvNodeBase * node )
{
  static const char method_name[] = "MapvBase::remove" ;

  if ( container(node) != this ) {
    std::string msg(method_name);
    msg.append(" given object not in this container");
    throw std::invalid_argument( msg );
  }

  if ( 1 == Count ) { // The last node ?

    if ( node != leftmost() || node != rightmost() || node != nRoot() ) {
      std::string msg(method_name);
      msg.append(" internal data structure corrupted" );
      throw std::runtime_error( msg );
    }

    leftmost( nREnd() );
    rightmost( nEnd() );
    root(0);
    Count = 0 ;
    header()->color = red ;
    node->left = node->right = node->parent = 0 ; node->color = 0 ;
    return ;
  }

  MapvNodeBase * z = node ;
  MapvNodeBase * y = node ;
  MapvNodeBase * x = 0 ;
  MapvNodeBase * x_parent = 0 ;

  // Ready to remove

  if ( y->left == 0 ) {       // z has at most one non-null child. y == z
    x = y->right ;            // x might be null
  }
  else if ( y->right == 0 ) { // z has exactly one non-null child. y == z
    x = y->left ;             // z is not null
  }
  else {                      // z has two non-null children.
     y = y->right ;           // Set y to z's successor.
     while ( y->left ) y = y->left ;
     x = y->right ;           // x might be null
  }

  if ( y != z ) { // relink y in place of z. y is z's successor
    z->left->parent = y ;
    y->left = z->left ;
    if ( y != z->right ) {
      x_parent = y->parent ;
      if ( x ) x->parent = x_parent ;
      y->parent->left = x;   // y must be a left child
      y->right = z->right;
      z->right->parent = y;
    } else {
      x_parent = y;  // needed in case x == 0
    }
    if ( nRoot() == z) {
      root(y);
    }
    else if ( z->parent->left == z) {
      z->parent->left = y;
    }
    else {
      z->parent->right = y;
    }
    y->parent = z->parent;
    { int c = y->color; y->color = z->color; z->color = c ; }
    y = z;
    // y points to node to be actually deleted
  }
  else {  // y == z
    x_parent = y->parent ;
    if ( x ) x->parent = x_parent ; // possibly x == 0
    if ( nRoot() == z) {
      root(x);
    }
    else if ( z->parent->left == z ) {
      z->parent->left = x;
    }
    else {
      z->parent->right = x;
    }
    if ( leftmost() == z )  {
      if ( z->right == 0 ) { // z->left must be null also
	// makes leftmost() == nEnd() if z == nRoot()
	leftmost( z->parent );
      }
      else {
	leftmost( minimum(x) );
      }
    }
    if ( rightmost() == z )  {
      if ( z->left == 0 ) { // z->right must be null also
	// makes rightmost() == nEnd() if z == nRoot()
	rightmost( z->parent );
      }
      else { // x == z->left
	rightmost( maximum(x) );
      }
    }
  }
  if ( y->color != red ) {
    while ( x != nRoot() && ( x == 0 || x->color == black ) ) {
      if ( x == x_parent->left ) {
	MapvNodeBase * w = x_parent->right ;
	if ( w->color == red ) {
	  w->color        = black;
	  x_parent->color = red;
	  rotate_left(x_parent);
	  w = x_parent->right ;
	}
	if ((w->left  == 0 || w->left->color  == black) &&
	    (w->right == 0 || w->right->color == black)) {
	  w->color = red ;
	  x = x_parent ;
	  x_parent = x_parent->parent ;
	}
	else {
	  if (w->right == 0 || w->right->color == black) {
	      if ( w->left ) w->left->color = black;
	      w->color = red;
	      rotate_right(w);
	      w = x_parent->right ;
	  }
	  w->color = x_parent->color ;
	  x_parent->color = black;
	  if ( w->right ) w->right->color = black;
	  rotate_left(x_parent);
	  break;
	}
      }
      else {  // same as then clause with "right" and "left" exchanged
	MapvNodeBase * w = x_parent->left ;
	if ( w->color == red ) {
	  w->color = black;
	  x_parent->color = red;
	  rotate_right(x_parent);
	  w = x_parent->left ;
	}
	if ((w->right == 0 || w->right->color == black) &&
	    (w->left  == 0 || w->left->color  == black)) {
	  w->color = red;
	  x = x_parent ;
	  x_parent = x_parent->parent ;
	}
	else {
	  if ( w->left == 0 || w->left->color == black ) {
	    if ( w->right ) w->right->color = black;
	    w->color = red;
	    rotate_left(w);
	    w = x_parent->left ;
	  }
	  w->color = x_parent->color ;
	  x_parent->color = black;
	  if ( w->left ) w->left->color = black;
	  rotate_right(x_parent);
	  break;
	}
      }
    }
    if ( x ) x->color = black;
  }

  y->left = y->right = y->parent = 0 ; y->color = 0 ;

  --Count ; // Decrement the tree's count
}
Пример #16
0
void MapvBase::insert( MapvNodeBase * y , MapvNodeBase * z , bool z_lt_y )
{
  z->remove_from_container();

  if ( y == nEnd() ) { // First node inserted
    root(z);
    leftmost(z);
    rightmost(z);
    z->parent = header() ; // header is 'super-root'
  }
  else {
    if ( z_lt_y ) {
      y->left = z ;
      // maintain leftmost() pointing to minimum node
      if ( y == leftmost() ) leftmost(z);
    }
    else {
      y->right = z;
      // maintain rightmost() pointing to maximum node
      if ( y == rightmost() ) rightmost(z);
    }
    z->parent = y ;
  }
  z->left  = 0 ;
  z->right = 0 ;
  z->color = red ;
  ++Count ;

  // -------------------------------------------------------------------
  // Rebalance, 'y' and 'z' are reused as a local variable

  while ( z != nRoot() && z->parent->color == red ) {
    if ( z->parent == z->parent->parent->left ) {
      y = z->parent->parent->right ;
      if ( y && y->color == red ) {
	z->parent->color         = black;
	y->color                 = black;
	z->parent->parent->color = red;
	z = z->parent->parent ;
      }
      else {
	if ( z == z->parent->right ) {
	    z = z->parent ;
	    rotate_left(z);
	}
	z->parent->color         = black;
	z->parent->parent->color = red;
	rotate_right( z->parent->parent );
      }
    }
    else {
      y = z->parent->parent->left ;
      if ( y && y->color == red ) {
	z->parent->color         = black;
	y->color                 = black;
	z->parent->parent->color = red;
	z = z->parent->parent ;
      }
      else {
	if ( z == z->parent->left ) {
	    z = z->parent ;
	    rotate_right(z);
	}
	z->parent->color         = black;
	z->parent->parent->color = red;
	rotate_left(z->parent->parent);
      }
    }
  }
  nRoot()->color = black;
}
Пример #17
0
void FTVectoriser::ProcessContours()
{
    short contourLength = 0;
    short startIndex = 0;
    short endIndex = 0;

    contourList = new FTContour*[ftContourCount];

    for(int i = 0; i < ftContourCount; ++i)
    {
        FT_Vector* pointList = &outline.points[startIndex];
        char* tagList = &outline.tags[startIndex];

        endIndex = outline.contours[i];
        contourLength =  (endIndex - startIndex) + 1;

        FTContour* contour = new FTContour(pointList, tagList, contourLength);

        contourList[i] = contour;

        startIndex = endIndex + 1;
    }

    // Compute each contour's parity. FIXME: see if FT_Outline_Get_Orientation
    // can do it for us.
    for(int i = 0; i < ftContourCount; i++)
    {
        FTContour *c1 = contourList[i];

        // 1. Find the leftmost point.
        FTPoint leftmost(65536.0, 0.0);

        for(size_t n = 0; n < c1->PointCount(); n++)
        {
            FTPoint p = c1->Point(n);
            if(p.X() < leftmost.X())
            {
                leftmost = p;
            }
        }

        // 2. Count how many other contours we cross when going further to
        // the left.
        int parity = 0;

        for(int j = 0; j < ftContourCount; j++)
        {
            if(j == i)
            {
                continue;
            }

            FTContour *c2 = contourList[j];

            for(size_t n = 0; n < c2->PointCount(); n++)
            {
                FTPoint p1 = c2->Point(n);
                FTPoint p2 = c2->Point((n + 1) % c2->PointCount());

                /* FIXME: combinations of >= > <= and < do not seem stable */
                if((p1.Y() < leftmost.Y() && p2.Y() < leftmost.Y())
                    || (p1.Y() >= leftmost.Y() && p2.Y() >= leftmost.Y())
                    || (p1.X() > leftmost.X() && p2.X() > leftmost.X()))
                {
                    continue;
                }
                else if(p1.X() < leftmost.X() && p2.X() < leftmost.X())
                {
                    parity++;
                }
                else
                {
                    FTPoint a = p1 - leftmost;
                    FTPoint b = p2 - leftmost;
                    if(b.X() * a.Y() > b.Y() * a.X())
                    {
                        parity++;
                    }
                }
            }
        }

        // 3. Make sure the glyph has the proper parity.
        c1->SetParity(parity);
    }
}
Пример #18
0
t_ftmap_node const			*ftm_cbegin(t_ftmap const *set)
{
	if (set->head != NULL)
		return (leftmost(set->head));
	return (NULL);
}
Пример #19
0
t_ftmap_node const			*ftm_cnext(t_ftmap_node const *node)
{
	if (node->r != NULL)
		return (leftmost(node->r));
	return (first_topright_parent(node));
}