예제 #1
0
END_TEST

START_TEST(test_node_delete)
{
    node *root = node_new("d", "definition");
    node *l = node_new("b", "b");
    node *ll = node_new("a", "a");
    node *lr = node_new("c", "c");

    node_insert(root, l);
    node_insert(root, ll);
    node_insert(root, lr);

    // ensure correct insertions
    ck_assert_ptr_eq(l, root->left);
    ck_assert_ptr_eq(ll, root->left->left);
    ck_assert_ptr_eq(lr, root->left->right);

    ck_assert_int_eq(4, node_size(root));

    ck_assert_ptr_eq(l, node_delete(root, "b"));

    // ensure correct reinsertion
    ck_assert_ptr_eq(ll, root->left);
    ck_assert_ptr_eq(NULL, root->right);
    ck_assert_ptr_eq(NULL, root->left->left);
    ck_assert_ptr_eq(lr, root->left->right);

    // node is not found in the tree anymore
    ck_assert_ptr_eq(NULL, node_search(root, "b"));

    ck_assert_int_eq(3, node_size(root));

    node_free(root);
}
예제 #2
0
static splaytree_node* insert(splaytree *tree, splaytree_node *n, VALUE key, VALUE value) {
	int cmp;
	splaytree_node *new_node;
	
	if (n) {
		n = splay(tree, n, key);
		cmp = tree->compare_function(key, n->key);
		if (cmp == 0) {
			n->value = value;
			return n;
		}
	}
	new_node = create_node(key, value);
	if (!n) {
		new_node->left = new_node->right = NULL;
	} else {
		cmp = tree->compare_function(key, n->key);
		if (cmp < 0) {
			new_node->left = n->left;
			new_node->right = n;
			n->left = NULL;
			n->size = 1 + node_size(n->right);
		} else {
			new_node->right = n->right;
			new_node->left = n;
			n->right = NULL;
			n->size = 1 + node_size(n->left);
		}
	}
	new_node->size = 1 + node_size(new_node->left) + node_size(new_node->right);
	return new_node;
}
예제 #3
0
파일: fg.cpp 프로젝트: Armour/powercrust
Tree * insert(site i, Tree * t) {
    /* Insert key i into the tree t, if it is not already there. */
    /* Return a pointer to the resulting tree.                   */
    Tree * newT;

    if (t != NULL) {
        t = splay(i,t);
        if (compare(i, t->key)==0) {
            return t;  /* it's already there */
        }
    }
    NEWL(Tree,newT)
        if (!t) {
            newT->left = newT->right = NULL;
        } else if (compare(i, t->key) < 0) {
            newT->left = t->left;
            newT->right = t;
            t->left = NULL;
            t->size = 1+node_size(t->right);
        } else {
            newT->right = t->right;
            newT->left = t;
            t->right = NULL;
            t->size = 1+node_size(t->left);
        }
    newT->key = i;
    newT->size = 1 + node_size(newT->left) + node_size(newT->right);
    return newT;
}
예제 #4
0
void widget_sprite_update() {
	struct node *this = _current_node;
	struct widget_sprite *wgspr = (struct widget_sprite *)_current_widget;
	

	if(wgspr->reset) {
		wgspr->reset = false;

		//标记整个区域需要重绘
		this->mask |= NMSK_BOUNDS;
	}

	if(wgspr->sheet != NULL) {
		spritesheet_update(wgspr->sheet,G->now);
		rect *current = spritesheet_get_rect(wgspr->sheet);
		if(wgspr->current != current) {
			wgspr->current = current;
			//标记整个区域需要重绘
			this->mask |= NMSK_BOUNDS;
		}
	}

	if(wgspr->sheet != NULL && wgspr->current != NULL) {
		node_size(this,wgspr->current->w, wgspr->current->h);
	} else {
		node_size(this,0,0);
	}
}
예제 #5
0
파일: yaml.c 프로젝트: kazufusa/kanabo
static bool emit_tagged_scalar(const node *scalar, yaml_char_t *tag, yaml_scalar_style_t style, int implicit, void *context)
{
    trace_string("emitting scalar \"%s\"", scalar_value(scalar), node_size(scalar));
    yaml_emitter_t *emitter = (yaml_emitter_t *)context;
    yaml_event_t event;

    yaml_scalar_event_initialize(&event, NULL, tag, scalar_value(scalar), (int)node_size(scalar), implicit, implicit, style);
    if (!yaml_emitter_emit(emitter, &event))
        return false;

    return true;
}
예제 #6
0
static int
node_size(node_t* n)
{
 if (n->leaf != 0)
    {
      return 1;
    }
  else
    {
      return node_size((node_t*) n->left) + node_size((node_t*) n->right);
    }
}
예제 #7
0
파일: bst-seq.c 프로젝트: LPD-EPFL/ASCYLIB
static int
node_size(volatile node_t* n)
{
  if (n == NULL)
    {
      return 0;
    }
  else
    {
      return 1 + node_size(n->left) + node_size(n->right);
    }
}
예제 #8
0
inline void page_pickSchedule() {
  static byte prev_index = 0;
  if(pre_page != PICK_SCHEDULE) {
    PTLS(" Page Pick Schedule");
    lcd.cursor();
    pre_page = PICK_SCHEDULE; 
    node_index = node_index % (node_size()-1);
    prev_index = node_index + 1;
  }
  
  if (prev_index != node_index) {
    prev_index == node_index;
    schedule s = node_get(node_index);
    String t = getTimeString(s);
    if (mod) lcd.print(F("Mod:"));
    else lcd.print(F("Del: "));
    lcd.print(t);
    lcd.setCursor(0,1);
    lcd.print("Targ Temp: " + (String)s.temperature);
  }
  
  if (button_input == PLUS_UP || button_input == PLUS_HOLD)
  {
    node_index += 1;
    if (node_index >= node_size())
      node_index = 0;
  }
  else if (button_input == MINUS_UP || button_input == MINUS_HOLD)
  {
    node_index -= 1;
    if(node_index < 0) {
      node_index = (node_size()-1);
    }
  }
  else if (button_input == SET_UP)
  {
    if(mod) {
      switchPage(MODIFY_SCHEDULE);
    } else {
      PTLS("Node deleted");
      node_delete(node_index);
      node_index = (node_size()-1);
      prev_index = node_index + 1;
    }
  }
  else if (button_input == MODE_UP)
  {
    switchPage(LIST_MODE);
  }
}
예제 #9
0
static off_t del_push(brtr_t *b, off_t r, size_t size, off_t id)
/* puts a node in the delete tree */
{
    struct brtr_node *n;
    struct brtr_node *m;

    if ((n = brtr_node(b, r)) != NULL) {
        size_t ns = node_size(n->ksize, n->vsize);

        if (size < ns)
            r = set_left(b, r, del_push(b, n->left, size, id));
        else
        if (size > ns)
            r = set_right(b, r, del_push(b, n->right, size, id));
        else {
            /* a node of this size already exist;
               enqueue to its stree */
            m = brtr_node(b, id);

            m->stree = n->stree;
            n->stree = id;
        }
    }
    else {
        m = brtr_node(b, id);

        m->left = m->right = m->stree = 0;
        m->c = 1;

        r = id;
    }

    return r;
}
예제 #10
0
static off_t del_pull(brtr_t *b, off_t r, size_t size, off_t *id)
/* pulls a node with the specified size from the delete queue */
{
    struct brtr_node *n;

    if ((n = brtr_node(b, r)) != NULL) {
        size_t ns = node_size(n->ksize, n->vsize);

        if (size < ns)
            r = set_left(b, r, del_pull(b, n->left, size, id));
        else
        if (size > ns)
            r = set_right(b, r, del_pull(b, n->right, size, id));
        else {
            struct brtr_node *m;

            /* found; does the node has an stree of equal nodes? */
            if ((m = brtr_node(b, n->stree)) != NULL) {
                *id = n->stree;
                n->stree = m->stree;
            }
            else {
                /* unique node: return it */
                *id = r;
                r = merge_nodes(b, n->left, n->right);
            }
        }
    }

    return r;
}
예제 #11
0
static off_t clone_node(brtr_t *b, struct brtr_node *n, off_t l, off_t r)
/* creates a node almost equal to n */
{
    size_t s;
    struct brtr_node *c;
    off_t id;

    /* create a local copy of the node, to avoid possible relocations
       of the original due to a do_mmap() in brtr_alloc() */
    s = node_size(n->ksize, n->vsize);
    c = malloc(s);
    memcpy(c, n, s);

    /* avoid destroying the stree NODE_MODIFY */
    n->f &= ~(BRTR_FLAG_STREE);

    id = brtr_alloc(b,
        brtr_node_key(c),   c->ksize,
        brtr_node_value(c), c->vsize,
        l, r, c->f
    );

    free(c);

    return id;
}
예제 #12
0
파일: tree.c 프로젝트: FromPointer/nessDB
enum reactivity get_reactivity(struct tree *t, struct node *node)
{
	uint32_t children = node->n_children;

	if (nessunlikely(node->height == 0)) {
		if (node_size(node) >= t->e->leaf_default_node_size)
			return FISSIBLE;
	} else {
		if (children >= t->e->inner_node_fanout)
			return FISSIBLE;

		if (node_size(node) >= t->e->inner_default_node_size)
			return FLUSHBLE;
	}

	return STABLE;
}
예제 #13
0
파일: api.c 프로젝트: kazufusa/kanabo
node *sequence_get(const node *sequence, size_t index)
{
    PRECOND_NONNULL_ELSE_NULL(sequence);
    PRECOND_ELSE_NULL(SEQUENCE == node_kind(sequence));
    PRECOND_ELSE_NULL(index < node_size(sequence));

    return vector_get(sequence->content.sequence, index);
}
예제 #14
0
파일: fg.cpp 프로젝트: Armour/powercrust
Tree *find_rank(int r, Tree *t) {
    /* Returns a pointer to the node in the tree with the given rank.  */
    /* Returns NULL if there is no such node.                          */
    /* Does not change the tree.  To guarantee logarithmic behavior,   */
    /* the node found here should be splayed to the root.              */
    int lsize;
    if ((r < 0) || (r >= node_size(t))) return NULL;
    for (;;) {
        lsize = node_size(t->left);
        if (r < lsize) {
            t = t->left;
        } else if (r > lsize) {
            r = r - lsize -1;
            t = t->right;
        } else {
            return t;
        }
    }
}
예제 #15
0
/* ---------------------------------------------------------------------- */
static btnode node_Make(BTREE tree, void *data)
{
  btnode ret;

  ret = malloc(node_size(tree) + elem_size(tree));

  if (ret) {
    data_copy(tree, data(tree, ret), data);
    parent(ret) = left(ret) = right(ret) = NULL;
  }
  return ret;
}
예제 #16
0
파일: ast.c 프로젝트: chain78/none
Node *newNode(Type type,int cnt,...){
    Node *node = NULL;
    va_list args;
    node = malloc(node_size(cnt));
    if(node){
        node->type = type;
        node->cnt = cnt;
        va_start(args,cnt);
        for(int i = 0;i < cnt;i++){
            node->nodes[i] = va_arg(args,YYSTYPE);
        }
        va_end(args);
    }
    return node;
}
예제 #17
0
파일: ast.c 프로젝트: chain78/none
Node *insertNode(Node *dest,int cnt,...){
    Node *node = NULL;
    va_list args;
    if(!dest)
        return NULL;
    node = realloc(dest,node_size(dest->cnt + cnt));
    if(node){
        va_start(args,cnt);
        for(int i = 0;i < cnt;i++){
            node->nodes[node->cnt + i].node = va_arg(args,Node *);
        }
        va_end(args);
        node->cnt += cnt;
    }
    return node;
}
void generate_R_dendrogram(int * const merge, double * const height, int * const order, cluster_result & Z2, const int N) {
  // The array "nodes" is a union-find data structure for the cluster
  // identites (only needed for unsorted cluster_result input).
  union_find nodes(sorted ? 0 : N);
  if (!sorted) {
    std::stable_sort(Z2[0], Z2[N-1]);
  }

  t_index node1, node2;
  auto_array_ptr<t_index> node_size(N-1);

  for (t_index i=0; i<N-1; ++i) {
    // Get two data points whose clusters are merged in step i.
    // Find the cluster identifiers for these points.
    if (sorted) {
      node1 = Z2[i]->node1;
      node2 = Z2[i]->node2;
    }
    else {
      node1 = nodes.Find(Z2[i]->node1);
      node2 = nodes.Find(Z2[i]->node2);
      // Merge the nodes in the union-find data structure by making them
      // children of a new node.
      nodes.Union(node1, node2);
    }
    // Sort the nodes in the output array.
    if (node1>node2) {
      t_index tmp = node1;
      node1 = node2;
      node2 = tmp;
    }
    /* Conversion between labeling conventions.
       Input:  singleton nodes 0,...,N-1
               compound nodes  N,...,2N-2
       Output: singleton nodes -1,...,-N
               compound nodes  1,...,N
    */
    merge[i]     = (node1<N) ? -static_cast<int>(node1)-1
                              : static_cast<int>(node1)-N+1;
    merge[i+N-1] = (node2<N) ? -static_cast<int>(node2)-1
                              : static_cast<int>(node2)-N+1;
    height[i] = Z2[i]->dist;
    node_size[i] = size_(node1) + size_(node2);
  }

  order_nodes(N, merge, node_size, order);
}
예제 #19
0
void brtr_free(brtr_t *b, off_t id)
{
    struct brtr_node *n;

    /* get node */
    n = brtr_node(b, id);

    /* if this node stores a subtree, destroy it */
    if (n->f & BRTR_FLAG_STREE)
        brtr_destroy(b, n->stree);

    if (b->fdes != -1) {
        /* add to the deleted tree */
        b->hdr->del = del_push(b, b->hdr->del, node_size(n->ksize, n->vsize), id);
    }
    else
        free(n);
}
예제 #20
0
END_TEST

START_TEST (nodes)
{
    reset_errno();
    Node *r = model_document_root(model, 0);
    assert_noerr();
    assert_not_null(r);
    assert_node_kind(r, MAPPING);

    reset_errno();
    unsigned char *n = node_name(r);
    assert_noerr();
    assert_null(n);

    reset_errno();
    size_t s = node_size(r);
    assert_noerr();
    assert_uint_eq(4, s);
}
예제 #21
0
void check_serial_cmd()
{
	while (Serial.available())
	{
		delay(1);
		static String command;
		char input = Serial.read();

		if (input == '\r')
		{

		} 
		else if (input == '\n')
		{
			if (command.equals(("size")))
			{
				PTS("Schedule size: ");
				PTL(node_size());
			} else if (command.equals(("mem"))) {
				PTLS("Reading");
				for (int i = 0; i < MAX_NODE; i++) {
					schedule s = node_get(i);
					PT(i); PTS(", ");
					PT(s.day); PTS(", ");
					PT(s.hour); PTS(", ");
					PT(s.minute); PTS(", ");
					PT(s.temperature); PTL();
				}
			} else if (command.equals(("RESET"))) {
				PTLS("Resetting Memory");
				node_RESET();
			}
			command = "";
		}
		else
		{
			command.concat(input);
		}

	}
}
예제 #22
0
파일: cache.c 프로젝트: tonicbupt/nessDB
void cache_unpin(struct cache_file *cf, struct node *n)
{
	struct cpair *p;
	struct cache *c = cf->cache;

	/*
	 * here, we don't need a hashtable array lock,
	 * since we have hold the pair->value_lock,
	 * others(evict thread) can't remove it from cache
	 */
	p = cpair_htable_find(c->table, n->nid);
	nassert(p);

	n->attr.oldsz = n->attr.newsz;
	n->attr.newsz = node_size(n);
	mutex_lock(&c->mtx);
	c->cache_size += (n->attr.newsz - n->attr.oldsz);
	mutex_unlock(&c->mtx);

	write_unlock(&p->value_lock);
}
예제 #23
0
END_TEST

START_TEST(test_node_insert)
{
    node *root = node_new("b", "definition");
    node *l = node_new("a", "a");
    node *r = node_new("c", "c");

    node_insert(root, l);
    node_insert(root, r);

    ck_assert_ptr_eq(l, root->left);
    ck_assert_ptr_eq(r, root->right);

    ck_assert_str_eq("a", root->left->definition);
    ck_assert_str_eq("c", root->right->definition);

    ck_assert_int_eq(3, node_size(root));

    node_free(root);
}
예제 #24
0
파일: rope.c 프로젝트: Daniel-NJ/librope
// Allocate and return a new node. The new node will be full of junk, except
// for its height.
// This function should be replaced at some point with an object pool based version.
static rope_node *alloc_node(rope *r, uint8_t height) {
  rope_node *node = (rope_node *)r->alloc(node_size(height));
  node->height = height;
  return node;
}
예제 #25
0
 /// \effects Allocates an \concept{concept_array,array} of nodes by searching for \c n continuous nodes on the list and removing them.
 /// Depending on the \c PoolType this can be a slow operation or not allowed at all.
 /// This can sometimes lead to a growth, even if technically there is enough continuous memory on the free list.
 /// \returns An array of \c n nodes of size \ref node_size() suitable aligned.
 /// \throws Anything thrown by the used implementation allocator's allocation function if a growth is needed,
 /// or \ref bad_allocation_size if <tt>n * node_size()</tt> is too big.
 /// \requires The \c PoolType must support array allocations, otherwise the body of this function will not compile.
 /// \c n must be valid \concept{concept_array,array count}.
 void* allocate_array(std::size_t n)
 {
     static_assert(pool_type::value,
                 "does not support array allocations");
     return allocate_array(n, node_size());
 }
예제 #26
0
파일: tree.c 프로젝트: FromPointer/nessDB
/*
 * 	+-----------------------------------------------+
 * 	| 	5 	| 	7 	| 	9 	|
 * 	+-----------------------------------------------+
 * 				|
 * 			+---------------+
 * 			|  60 | 61 | 62 |
 * 			+---------------+
 *
 * 	+---------------------------------------------------------------+
 * 	|  	5 	| 	60	 |	7 	| 	9 	|
 * 	+---------------------------------------------------------------+
 * 				|		|
 * 			    +--------+	    +---------+
 * 			    |   60   |	    | 61 | 62 |
 * 			    +--------+	    +---------+
 *
 *
 * ENTER:
 *	- node is already locked(L_WRITE)
 * EXITS:
 *	- a is locked(L_WRITE)
 *	- b is locked(L_WRITE)
 */
static void _node_split(struct tree *t,
                        struct node *node,
                        struct node **a,
                        struct node **b,
                        struct msg **split_key)
{
	int i;
	int pivots_old;
	int pivots_in_a;
	int pivots_in_b;
	struct node *nodea;
	struct node *nodeb;
	struct msg *spk;

	__DEBUG("nonleaf split begin, NID %"PRIu64""
	        ", nodesz %d"
	        ", nodec %d"
	        ", children %d"
	        , node->nid
	        , node_size(node)
	        , node_count(node)
	        , node->n_children);

	nodea = node;
	pivots_old = node->n_children - 1;
	nassert(pivots_old > 2);

	pivots_in_a = pivots_old / 2;
	pivots_in_b = pivots_old - pivots_in_a;

	/* node a */
	nodea->n_children = pivots_in_a + 1;

	/* node b */
	NID nid = hdr_next_nid(t->hdr);
	node_create_light(nid, node->height > 0 ? 1 : 0, pivots_in_b + 1, t->hdr->version, t->e, &nodeb);
	cache_put_and_pin(t->cf, nid, nodeb);

	for (i = 0; i < (pivots_in_b); i++)
		nodeb->pivots[i] = nodea->pivots[pivots_in_a + i];

	for (i = 0; i < (pivots_in_b + 1); i++)
		nodeb->parts[i] = nodea->parts[pivots_in_a + i];

	/* the rightest partition of nodea */
	struct child_pointer *ptr = &nodea->parts[pivots_in_a].ptr;

	if (nodea->height > 0)
		ptr->u.nonleaf = create_nonleaf(t->e);
	else
		ptr->u.leaf = create_leaf(t->e);


	/* split key */
	spk = msgdup(&node->pivots[pivots_in_a - 1]);

	node_set_dirty(nodea);
	node_set_dirty(nodeb);

	__DEBUG("nonleaf split end, nodea NID %"PRIu64""
	        ", nodesz %d"
	        ", nodec %d"
	        ", children %d"
	        , nodea->nid
	        , node_size(nodea)
	        , node_count(nodea)
	        , nodea->n_children);

	__DEBUG("nonleaf split end, nodeb NID %"PRIu64""
	        ", nodesz %d"
	        ", nodec %d"
	        ", children %d"
	        , nodeb->nid
	        , node_size(nodeb)
	        , node_count(nodeb)
	        , nodeb->n_children);

	*a = nodea;
	*b = nodeb;
	*split_key = spk;
}
예제 #27
0
파일: tree.c 프로젝트: FromPointer/nessDB
/*
 * EFFECT:
 *	- split leaf&lmb into two leaves:a & b
 *	  a&b are both the half of the lmb
 *
 * PROCESS:
 *	- leaf:
 *		+-----------------------------------+
 *		|  0  |  1  |  2  |  3  |  4  |  5  |
 *		+-----------------------------------+
 *
 *	- split:
 *				   root
 *				 +--------+
 *				 |   2    |
 *				 +--------+
 *	  	                /          \
 *	    	+-----------------+	 +------------------+
 *	    	|  0  |  1  |  2  |	 |  3  |  4  |  5   |
 *	    	+-----------------+	 +------------------+
 *	    	      nodea			nodeb
 *
 * ENTER:
 *	- leaf is already locked (L_WRITE)
 * EXITS:
 *	- a is locked
 *	- b is locked
 */
static void _leaf_and_lmb_split(struct tree *t,
                                struct node *leaf,
                                struct node **a,
                                struct node **b,
                                struct msg **split_key)
{
	struct child_pointer *cptra;
	struct child_pointer *cptrb;
	struct node *leafa;
	struct node *leafb;
	struct lmb *mb;
	struct lmb *mba;
	struct lmb *mbb;
	struct msg *sp_key = NULL;

	__DEBUG("leaf split begin, NID %"PRIu64""
	        ", nodesz %d"
	        ", nodec %d"
	        ", children %d"
	        , leaf->nid
	        , node_size(leaf)
	        , node_count(leaf)
	        , leaf->n_children);

	leafa = leaf;
	cptra = &leafa->parts[0].ptr;

	/* split lmb of leaf to mba & mbb */
	mb = cptra->u.leaf->buffer;
	lmb_split(mb, &mba, &mbb, &sp_key);
	lmb_free(mb);

	/* reset leafa buffer */
	cptra->u.leaf->buffer = mba;

	/* new leafb */
	NID nid = hdr_next_nid(t->hdr);
	node_create(nid, 0, 1, t->hdr->version, t->e, &leafb);
	cache_put_and_pin(t->cf, nid, leafb);

	cptrb = &leafb->parts[0].ptr;
	lmb_free(cptrb->u.leaf->buffer);
	cptrb->u.leaf->buffer = mbb;

	/* set dirty */
	node_set_dirty(leafa);
	node_set_dirty(leafb);

	__DEBUG("leaf split end, leafa NID %"PRIu64""
	        ", nodesz %d"
	        ", nodec %d"
	        ", children %d"
	        , leafa->nid
	        , node_size(leafa)
	        , node_count(leafa)
	        , leafa->n_children);

	__DEBUG("leaf split end, leafb NID %"PRIu64""
	        ", nodesz %d"
	        ", nodec %d"
	        ", children %d"
	        , leafb->nid
	        , node_size(leafb)
	        , node_count(leafb)
	        , leafb->n_children);

	*a = leafa;
	*b = leafb;
	*split_key = sp_key;
	status_increment(&t->e->status->tree_leaf_split_nums);
}
예제 #28
0
파일: bst-seq.c 프로젝트: LPD-EPFL/ASCYLIB
int 
set_size(intset_t* set)
{
  int size = node_size(set->head);;
  return size;
}
예제 #29
0
파일: fg.c 프로젝트: aka863/hull
Tree * splay (site i, Tree *t) 
/* Splay using the key i (which may or may not be in the tree.) */
/* The starting root is t, and the tree used is defined by rat  */
/* size fields are maintained */
{
    Tree N, *l, *r, *y;
    int comp, root_size, l_size, r_size;
    
    if (!t) return t;
    N.left = N.right = NULL;
    l = r = &N;
    root_size = node_size(t);
    l_size = r_size = 0;
 
    for (;;) {
        comp = compare(i, t->key);
        if (comp < 0) {
            if (!t->left) break;
            if (compare(i, t->left->key) < 0) {
                y = t->left;                           /* rotate right */
                t->left = y->right;
                y->right = t;
                t->size = node_size(t->left) + node_size(t->right) + 1;
                t = y;
                if (!t->left) break;
            }
            r->left = t;                               /* link right */
            r = t;
            t = t->left;
            r_size += 1+node_size(r->right);
        } else if (comp > 0) {
            if (!t->right) break;
            if (compare(i, t->right->key) > 0) {
                y = t->right;                          /* rotate left */
                t->right = y->left;
                y->left = t;
		t->size = node_size(t->left) + node_size(t->right) + 1;
                t = y;
                if (!t->right) break;
            }
            l->right = t;                              /* link left */
            l = t;
            t = t->right;
            l_size += 1+node_size(l->left);
        } else break;
    }
    l_size += node_size(t->left);  /* Now l_size and r_size are the sizes of */
    r_size += node_size(t->right); /* the left and right trees we just built.*/
    t->size = l_size + r_size + 1;

    l->right = r->left = NULL;

    /* The following two loops correct the size fields of the right path  */
    /* from the left child of the root and the right path from the left   */
    /* child of the root.                                                 */
    for (y = N.right; y != NULL; y = y->right) {
        y->size = l_size;
        l_size -= 1+node_size(y->left);
    }
    for (y = N.left; y != NULL; y = y->left) {
        y->size = r_size;
        r_size -= 1+node_size(y->right);
    }
 
    l->right = t->left;                                /* assemble */
    r->left = t->right;
    t->left = N.right;
    t->right = N.left;

    return t;
}
예제 #30
0
/* Splay using the key i (which may or may not be in the tree.)
 * The starting root is t, and the tree used is defined by rat
 * size fields are maintained */
splaytree_t *
splaytree_splay(splaytree_t *t, int i)
{
    splaytree_t N, *l, *r, *y;
    int comp, l_size, r_size;

    if (t == NULL) return t;
    N.left = N.right = NULL;
    l = r = &N;
    l_size = r_size = 0;

    for (;;) {
        comp = compare(i, t->key);
        if (comp < 0) {
            if (t->left == NULL) break;
            if (compare(i, t->left->key) < 0) {
                y = t->left;                           /* rotate right */
                t->left = y->right;
                y->right = t;
                t->size = node_size(t->left) + node_size(t->right) + 1;
                t = y;
                if (t->left == NULL) break;
            }
            r->left = t;                               /* link right */
            r = t;
            t = t->left;
            r_size += 1+node_size(r->right);
        } else if (comp > 0) {
            if (t->right == NULL) break;
            if (compare(i, t->right->key) > 0) {
                y = t->right;                          /* rotate left */
                t->right = y->left;
                y->left = t;
        t->size = node_size(t->left) + node_size(t->right) + 1;
                t = y;
                if (t->right == NULL) break;
            }
            l->right = t;                              /* link left */
            l = t;
            t = t->right;
            l_size += 1+node_size(l->left);
        } else {
            break;
        }
    }
    l_size += node_size(t->left);  /* Now l_size and r_size are the sizes of */
    r_size += node_size(t->right); /* the left and right trees we just built.*/
    t->size = l_size + r_size + 1;

    l->right = r->left = NULL;

    /* The following two loops correct the size fields of the right path  */
    /* from the left child of the root and the right path from the left   */
    /* child of the root.                                                 */
    for (y = N.right; y != NULL; y = y->right) {
        y->size = l_size;
        l_size -= 1+node_size(y->left);
    }
    for (y = N.left; y != NULL; y = y->left) {
        y->size = r_size;
        r_size -= 1+node_size(y->right);
    }

    l->right = t->left;                                /* assemble */
    r->left = t->right;
    t->left = N.right;
    t->right = N.left;

    return t;
}