1/*-------------------------------------------------------------------------
4 * A Pairing Heap implementation
6 * A pairing heap is a data structure that's useful for implementing
7 * priority queues. It is simple to implement, and provides amortized O(1)
8 * insert and find-min operations, and amortized O(log n) delete-min.
10 * The pairing heap was first described in this paper:
12 * Michael L. Fredman, Robert Sedgewick, Daniel D. Sleator, and Robert E.
14 * The pairing heap: a new form of self-adjusting heap.
15 * Algorithmica 1, 1 (January 1986), pages 111-129. DOI: 10.1007/BF01840439
17 * Portions Copyright (c) 2012-2025, PostgreSQL Global Development Group
20 * src/backend/lib/pairingheap.c
22 *-------------------------------------------------------------------------
35 * pairingheap_allocate
37 * Returns a pointer to a newly-allocated heap, with the heap property defined
38 * by the given comparator function, which will be invoked with the additional
39 * argument specified by 'arg'.
58 * Releases memory used by the given pairingheap.
60 * Note: The nodes in the heap are not freed!
69 * A helper function to merge two subheaps into one.
71 * The subheap with smaller value is put as a child of the other one (assuming
74 * The next_sibling and prev_or_parent pointers of the input nodes are
75 * ignored. On return, the returned node's next_sibling and prev_or_parent
76 * pointers are garbage.
86 /* swap 'a' and 'b' so that 'a' is the one with larger value */
96 /* and put 'b' as a child of 'a' */
98 a->first_child->prev_or_parent =
b;
99 b->prev_or_parent =
a;
100 b->next_sibling =
a->first_child;
109 * Adds the given node to the heap in O(1) time.
116 /* Link the new node as a new tree */
125 * Returns a pointer to the first (root, topmost) node in the heap without
126 * modifying the heap. The caller must ensure that this routine is not used on
127 * an empty heap. Always O(1).
138 * pairingheap_remove_first
140 * Removes the first (root, topmost) node in the heap and returns a pointer to
141 * it after rebalancing the heap. The caller must ensure that this routine is
142 * not used on an empty heap. O(log n) amortized.
152 /* Remove the root, and form a new heap of its children. */
167 * Remove 'node' from the heap. O(log n) amortized.
178 * If the removed node happens to be the root node, do it with
179 * pairingheap_remove_first().
188 * Before we modify anything, remember the removed node's first_child and
189 * next_sibling pointers.
195 * Also find the pointer to the removed node in its previous sibling, or
196 * if this is the first child of its parent, in its parent.
202 Assert(*prev_ptr == node);
205 * If this node has children, make a new subheap of the children and link
206 * the subheap in place of the removed node. Otherwise just unlink this
215 *prev_ptr = replacement;
221 *prev_ptr = next_sibling;
228 * Merge a list of subheaps into a single heap.
230 * This implements the basic two-pass merging strategy, first forming pairs
231 * from left to right, and then merging the pairs.
244 /* Walk the subheaps from left to right, merging in pairs */
256 /* last odd node at the end of list */
264 /* merge this and the next subheap, and add to 'pairs' list. */
272 * Merge all the pairs together to form a single heap.
281 newroot =
merge(heap, newroot, curr);
288 * A debug function to dump the contents of the heap as a string.
290 * The 'dumpfunc' callback appends a string representation of a single node
291 * to the StringInfo. 'opaque' can be used to pass more information to the
294#ifdef PAIRINGHEAP_DEBUG
308 dumpfunc(node,
buf, opaque);
311 pairingheap_dump_recurse(
buf, node->
first_child, dumpfunc, opaque, depth + 1, node);
312 prev_or_parent = node;
329 pairingheap_dump_recurse(&
buf, heap->
ph_root, dumpfunc, opaque, 0, NULL);
static int compare(const void *arg1, const void *arg2)
Assert(PointerIsAligned(start, uint64))
char * pstrdup(const char *in)
void pfree(void *pointer)
void pairingheap_remove(pairingheap *heap, pairingheap_node *node)
void pairingheap_add(pairingheap *heap, pairingheap_node *node)
static pairingheap_node * merge(pairingheap *heap, pairingheap_node *a, pairingheap_node *b)
pairingheap * pairingheap_allocate(pairingheap_comparator compare, void *arg)
pairingheap_node * pairingheap_remove_first(pairingheap *heap)
void pairingheap_free(pairingheap *heap)
pairingheap_node * pairingheap_first(pairingheap *heap)
static pairingheap_node * merge_children(pairingheap *heap, pairingheap_node *children)
#define pairingheap_is_empty(h)
int(* pairingheap_comparator)(const pairingheap_node *a, const pairingheap_node *b, void *arg)
void appendStringInfoSpaces(StringInfo str, int count)
void appendStringInfoChar(StringInfo str, char ch)
void initStringInfo(StringInfo str)
struct pairingheap_node * next_sibling
struct pairingheap_node * prev_or_parent
struct pairingheap_node * first_child
pairingheap_comparator ph_compare
pairingheap_node * ph_root