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; }
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; } }
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; }
/* --- 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 }
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; }
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 */ }
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; }
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); }
/* --- 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; }
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; }
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); }
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; }
shared_ptr<Heap> push(shared_ptr<Heap> h, Data v) { return meld(h, make_shared<Heap>(v)); }
/* --- 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 }
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); }
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); }
shared_ptr<Heap> pop(shared_ptr<Heap> h) { return meld(h->l, h->r); }
void pop() { node *t = root; root = meld(t->l, t->r); t.l = t.r = NULL; delete t; }
void push(const T& val) { root = meld(root, new node(val)); }
void meld(const meldable_heap<T>&& t) { root = meld(root, t.root); }
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); }