Exemplo n.º 1
0
shared_ptr<Heap> reduce(shared_ptr<Heap> h, shared_ptr<Heap> root, Data v) {
  if (v > h->val) return root;
  h->val = v;
  if (!h->p) return root;
  if (h->val < h->p->val) {
    if (h->p->l && h->p->l == h) {
      h->p->l.reset();
      return meld(h, root);
    } else {
      h->p->r.reset();
      return meld(h, root);
    }
  } else return root;
}
Exemplo n.º 2
0
void delete_min_phase_1(heap *h) {
    node *min = h->root;
    if (has_children(min)) {
        // Orphan all children
        node *first = min->child;
        node *curr  = min->child;
        do {
            curr->parent = NULL;
            curr = curr->right_sibling;
        } while (curr != first);

        // If the root has siblings, first cut it out of its sibling list
        // and then meld sibling and children lists
        if (has_siblings(min)) {
            node *rsib = min->right_sibling;
            cut_from_sibling_list(min);
            meld(first, rsib);
        }

        // Pick the first child as the new temporary root
        h->root = first;
    } else {
        // Due to the early return in the top, we are guaranteed that
        // if min has no children, it must have siblings, so we start
        // by cutting it out of its sibling list.
        node *sib = min->right_sibling;
        cut_from_sibling_list(min);

        // Pick a sibling (arbitrary) as the new temporary root
        h->root = sib;
    }
}
Exemplo n.º 3
0
node* insert(heap *h, int key) {
    // Create a brand new node
    node *n = (node*) malloc(sizeof(node));
    n->parent = NULL;
    n->child  = NULL;
    n->left_sibling  = n;
    n->right_sibling = n;
    n->key = key;
    n->rank = 0;
    n->marked = 0;
    n->data = NULL;

    // Meld it with the root of the heap, if it is non-null
    if (h->root != NULL) {
        meld(h->root, n);
        if (key < h->root->key) {
            h->root = n;
        }
    } else {
        h->root = n;
    }

    // Remember to update the size of the heap
    h->size++;
    return n;
}
Exemplo n.º 4
0
/* --- insert() ---
 * Inserts an item $item$ with associated key $k$ into the heap.
 */
void FHeap::insert(int item, float k)
{
    FHeapNode *newNode;

#if FHEAP_DUMP
printf("insert, ");
#endif

    /* create an initialise the new node */
    newNode = new FHeapNode;
    newNode->child = NULL;
    newNode->left = newNode->right = newNode;
    newNode->rank = 0;
    newNode->item = item;
    newNode->key = k;

    /* maintain a pointer to $item$'s new node in the heap */
    nodes[item] = newNode;

    /* meld the new node into the heap */
    meld(newNode);

    /* update the heaps node count */
    itemCount++;

#if FHEAP_DUMP
printf("insert-exited, ");
#endif
}
Exemplo n.º 5
0
 node *meld(node *a, node *b) {
     if (!a) return b;
     if (!b) return a;
     if (a->val > b->val) swap(a, b);
     a->r = meld(a->r, b);
     swap(a->l, a->r);
     return a;
 }
Exemplo n.º 6
0
Arquivo: skew.c Projeto: minicz/SimLua
static int skew_merge (lua_State *L) {
  heap *h1 = checkheap(L, 1);
  heap *h2 = checkheap(L, 2);
  lua_settop(L, 2);
  if (h2 == NULL) { lua_pop(L, 1); return 1; } /* h1 */
  meld(h1, h2);
  return 1; /* h2 */
}
Exemplo n.º 7
0
shared_ptr<Heap> meld(shared_ptr<Heap> a, shared_ptr<Heap> b) {
  if (!a) return b;
  if (!b) return a;
  if (a->val > b->val) swap(a, b);
  a->r = meld(a->r, b);
  swap(a->l, a->r);
  return a;
}
Exemplo n.º 8
0
void Token::meld(Ref<Token> root0, Ref<Token> root1)
{
	if ((!root0) || (!root1)) return;
	
	if (!root1->firstChild()) return;
	
	Token result_;
	Ref<Token, Pointer> result = &result_;
	Ref<Token, Owner> token0 = root0->firstChild();
	Ref<Token, Owner> token1 = root1->firstChild();
	
	// debug("Token::meld(): [%%: %%], [%%: %%]\n", root0->ruleName_, root0->countChildren(), root1->ruleName_, root1->countChildren());
	
	while (true)
	{
		bool take0 = (token0);
		bool take1 = (token1);
		if (take0 && take1) {
			take0 = (token0->i0_ < token1->i0_);
			take1 = !take0;
		}
		
		if (take0) {
			// debug("p0 [%%, %%, %%]\n", token0->ruleName_, token0->i0_, token0->i1_);
			Ref<Token, Owner> next0 = token0->nextSibling();
			Ref<Token> previousResult = result->lastChild();
			token0->unlink();
			result->insertChild(token0, previousResult);
			if (previousResult)
				token0->burn(previousResult->i0_, previousResult->i1_);
			token0 = next0;
		}
		else if (take1) {
			// debug("p1 [%%, %%, %%]\n", token1->ruleName_, token1->i0_, token1->i1_);
			Ref<Token, Owner> next1 = token1->nextSibling();
			Ref<Token> previousResult = result->lastChild();
			token1->unlink();
			if (previousResult) {
				if ((previousResult->i0_ < token1->i0_) && (token1->i1_ < previousResult->i1_)) {
					// see book 28/76: case 5
					Token dummy;
					dummy.appendChild(token1);
					meld(previousResult, &dummy);
					token1 = next1;
					continue;
				}
			}
			result->insertChild(token1, previousResult);
			if (previousResult)
				previousResult->burn(token1->i0_, token1->i1_);
			token1 = next1;
		}
		else
			break;
	}
	
	root0->appendAllChildrenOf(result);
}
Exemplo n.º 9
0
/* --- deleteMin() ---
 * Deletes and returns the minimum item from the heap.
 */
int FHeap::deleteMin()
{
    FHeapNode *minNode, *child, *next;
    float k, k2;
    int r, v, item;

#if FHEAP_DUMP
printf("deleteMin, ");
#endif

    /* First we determine the maximum rank in the heap. */
    v = treeSum;
    r = -1;
    while(v) {
        v = v >> 1;
        r++;
    };

    /* Now determine which root node is the minimum. */
    minNode = trees[r];
    k = minNode->key;
    while(r > 0) {
        r--;
        next = trees[r];
        if(next) {
            if((k2 = next->key) < k) {
                k = k2;
                minNode = next;
            }
            compCount++;
        }
    }

    /* We remove the minimum node from the heap but keep a pointer to it. */
    r = minNode->rank;
    trees[r] = NULL;
    treeSum -= (1 << r);

    child = minNode->child;
    if(child) meld(child);

    /* Record the vertex no of the old minimum node before deleting it. */
    item = minNode->item;
    nodes[item] = NULL;
    delete minNode;
    itemCount--;

#if FHEAP_DUMP
printf("deleteMin-exited, ");
#endif

    return item;
}
Exemplo n.º 10
0
shared_ptr<Heap> meld(
    shared_ptr<Heap> a, shared_ptr<Heap> b, shared_ptr<Heap> p = nullptr) {
  if (!a) {
    if (b) b->p = p;
    return b;
  }
  if (!b) {
    if (a) a->p = p;
    return a;
  }
  if (a->val > b->val) swap(a, b);
  a->p = p;
  a->r = meld(a->r, b, a);
  swap(a->l, a->r);
  return a;
}
Exemplo n.º 11
0
void insert_item(item* i, heap* h) {
  heap* new_h = make_heap();
  node* n = (node*)malloc(sizeof(node));
  n->key = i->key;
  n->rank = 0;
  n->marked = 0;
  n->item = i;
  n->parent = NULL;
  n->child = NULL;
  n->left_sibling = n;
  n->right_sibling = n;

  new_h->min_node = n;
  i->n = n;

  meld(h, new_h);  
}
Exemplo n.º 12
0
void decrease_key_cut(heap *h, node *n) {
    // Cut is only relevant on non-roots
    if (n->parent != NULL) {
        // Remember the parent
        node *parent = n->parent;

        // Then cut out the subtree, and insert as a new root
        cut_subtree(n);
        meld(h->root, n);

        // If the parent was marked, cut recursively
        if (parent->marked) {
            parent->marked = 0;
            decrease_key_cut(h, parent);
        } else {
            parent->marked = 1;
        }
    }

    // Update the heap minimum
    h->root = (n->key < h->root->key) ? n : h->root;
}
Exemplo n.º 13
0
shared_ptr<Heap> push(shared_ptr<Heap> h, Data v) {
  return meld(h, make_shared<Heap>(v));
}
Exemplo n.º 14
0
/* --- decreaseKey() ---
 * Decreases the key used for item $item$ to the value newValue.  It is left
 * for the user to ensure that newValue is in-fact less than the current value
 */
void FHeap::decreaseKey(int item, float newValue)
{
    FHeapNode *cutNode, *parent, *newRoots, *r, *l;
    int prevRank;

#if FHEAP_DUMP
printf("decreaseKey on vn = %d, ", item);
#endif

    /* Obtain a pointer to the decreased node and its parent then decrease the
     * nodes key.
     */
    cutNode = nodes[item];
    parent = cutNode->parent;
    cutNode->key = newValue;

    /* No reinsertion occurs if the node changed was a root. */
    if(!parent) {
#if FHEAP_DUMP
printf("decreaseKey-exited, ");
#endif
        return;
    }

    /* Update the left and right pointers of cutNode and its two neighbouring
     * nodes.
     */
    l = cutNode->left;
    r = cutNode->right;
    l->right = r;
    r->left = l;
    cutNode->left = cutNode->right = cutNode;

    /* Initially the list of new roots contains only one node. */
    newRoots = cutNode;

    /* While there is a parent node that is marked a cascading cut occurs. */
    while(parent && parent->marked) {

        /* Decrease the rank of cutNode's parent and update its child pointer.
         */
        parent->rank--;
        if(parent->rank) {
            if(parent->child == cutNode) parent->child = r;
        }
        else {
            parent->child = NULL;
        }

        /* Update the cutNode and parent pointers to the parent. */
        cutNode = parent;
        parent = cutNode->parent;

        /* Update the left and right pointers of cutNodes two neighbouring
         * nodes.
         */
        l = cutNode->left;
        r = cutNode->right;
        l->right = r;
        r->left = l;

        /* Add cutNode to the list of nodes to be reinserted as new roots. */
        l = newRoots->left;
        newRoots->left = l->right = cutNode;
        cutNode->left = l;
        cutNode->right = newRoots;
        newRoots = cutNode;
    }

    /* If the root node is being relocated then update the trees[] array.
     * Otherwise mark the parent of the last node cut.
     */
    if(!parent) {
        prevRank = cutNode->rank + 1;
        trees[prevRank] = NULL;
        treeSum -= (1 << prevRank);
    }
    else {
        /* Decrease the rank of cutNode's parent an update its child pointer.
         */
        parent->rank--;
        if(parent->rank) {
            if(parent->child == cutNode) parent->child = r;
        }
        else {
            parent->child = NULL;
        }

        parent->marked = 1;
    }

    /* Meld the new roots into the heap. */
    meld(newRoots);

#if FHEAP_DUMP
printf("decreaseKey-exited, ");
#endif
}
Exemplo n.º 15
0
void delete_min_phase_2(heap *h) {
    int max_rank = (int) ceil(2 * (log(h->size + 1) / log(2.0)));
    node *ranks[max_rank];
    for (int i = 0; i < max_rank; i++) {
        ranks[i] = NULL;
    }

    // The chain of root nodes is modified in the linking step, so to make
    // absolutely sure we go through all the root nodes, we store pointers
    // to them in an array, and iterate the array instead of depending on
    // the possibly shifty sibling list.
    int n = root_count(h);
    node **roots = (node**) malloc(n * sizeof(node*));

    // Populate the array
    node *current = h->root;
    for (int i = 0; i < n; i++) {
        roots[i] = current;
        current = current->right_sibling;
    }

    // Go through each node in the array
    for (int i = 0; i < n; i++) {
        node *curr = roots[i];

        // If there are pre-existing array entries, start linking
        while (ranks[curr->rank] != NULL) {
            // Determine winner and loser
            node *winner = (curr->key < ranks[curr->rank]->key ? curr : ranks[curr->rank]);
            node *loser  = (curr->key < ranks[curr->rank]->key ? ranks[curr->rank] : curr);

            // Null the array entry right away
            ranks[curr->rank] = NULL;

            // Update loser's parent pointer and promote winner
            loser->parent = winner;
            winner->rank += 1;

            // Cut loser out of its sibling list, and meld with the
            // children list of the winner (if any, otherwise just
            // set the loser as the only child of the winner).
            cut_from_sibling_list(loser);
            if (has_children(winner)) {
                meld(winner->child, loser);
            } else {
                winner->child = loser;
            }

            // Update current to be the winner
            curr = winner;
        }

        // Otherwise/finally, insert current into its place in the
        // array, and make it the temporary heap root.
        ranks[curr->rank] = curr;
        h->root = curr;
    }

    // Free the possibly HUGE array
    free(roots);
}
Exemplo n.º 16
0
pair<shared_ptr<Heap>, shared_ptr<Heap>> push(shared_ptr<Heap> h, Data v) {
  auto n = make_shared<Heap>(v);
  return make_pair(meld(h, n), n);
}
Exemplo n.º 17
0
shared_ptr<Heap> pop(shared_ptr<Heap> h) {
  return meld(h->l, h->r);
}
Exemplo n.º 18
0
 void pop() {
     node *t = root;
     root = meld(t->l, t->r);
     t.l = t.r = NULL;
     delete t;
 }
Exemplo n.º 19
0
 void push(const T& val) { root = meld(root, new node(val)); }
Exemplo n.º 20
0
 void meld(const meldable_heap<T>&& t) { root = meld(root, t.root); }
Exemplo n.º 21
0
shared_ptr<Heap> pop(shared_ptr<Heap> h) {
  if (h->l) h->l->p.reset();
  if (h->r) h->r->p.reset();
  return meld(h->l, h->r);
}