13struct PairingHeapNode {
14 PairingHeapNode(
const T& val) : _val(val), left(nullptr), right(nullptr), parent(nullptr) {}
16 PairingHeapNode(T&& val) : _val(std::move(val)), left(nullptr), right(nullptr), parent(nullptr) {}
18 template <
typename... Args,
typename =
decltype(T(std::declval<Args>()...))>
19 PairingHeapNode(Args&&... args) : _val(std::forward<Args>(args)...), left(
nullptr), right(
nullptr), parent(
nullptr) {}
22 void adopt(PairingHeapNode* child) {
37 if (parent->left ==
this) {
40 parent->right = right;
43 right->parent = parent;
50 PairingHeapNode *left, *right, *parent;
70template <
typename T,
typename Comp = std::less<T>>
73 using size_type = std::size_t;
74 using node_type = impl::PairingHeapNode<T>;
79 const T& operator*() {
return node->_val; }
81 const T* operator->() {
return &node->_val; }
83 bool operator==(
const iterator& rhs)
const {
return node == rhs.node; }
85 bool operator!=(
const iterator& rhs)
const {
return node != rhs.node; }
91 iterator(node_type* node) : node(node) {}
95 size_type
size()
const {
return _size; }
98 bool empty()
const {
return !root; }
101 const T&
top() {
return root->_val; }
115 auto node =
new node_type(t);
116 _merge_with(node, 1);
122 auto node =
new node_type(std::move(t));
123 _merge_with(node, 1);
129 template <
typename... Args>
131 auto node =
new node_type(std::forward<Args>(args)...);
132 _merge_with(node, 1);
149 auto* curr = root->left;
150 node_type* last =
nullptr;
154 auto next = curr->right;
160 auto next_next = next->right;
161 curr->parent =
nullptr;
162 curr->right =
nullptr;
163 next->parent =
nullptr;
164 next->right =
nullptr;
165 auto merged = _merge_node(curr, next);
166 merged->parent = last;
174 auto prev = last->parent;
176 auto prev_prev = prev->parent;
177 last->parent =
nullptr;
178 prev->parent =
nullptr;
179 last = _merge_node(last, prev);
180 last->parent = prev_prev;
193 _merge_with(other.root, other.size());
195 other.root =
nullptr;
205 if (it.node != root) {
207 it.node->_val = new_key;
208 _merge_with(it.node, 0);
210 root->_val = new_key;
221 if (it.node != root) {
223 it.node->adopt(root);
234 node_type* _merge_node(node_type* node1, node_type* node2) {
240 if (comp(node1->_val, node2->_val)) {
241 std::swap(node1, node2);
247 void _merge_with(node_type* other, size_type size_incr) {
248 root = _merge_node(root, other);
Definition: pairing_heap.hpp:78
Pairing heap, a pointer-based heap supporting efficient merge and decrease-key.
Definition: pairing_heap.hpp:71
size_type size() const
Returns the number of elements.
Definition: pairing_heap.hpp:95
iterator begin()
Returns an iterator to the top element, or a null-pointer iterator if the heap is empty.
Definition: pairing_heap.hpp:104
iterator push(T &&t)
Insert an element into the heap.
Definition: pairing_heap.hpp:121
void erase(iterator it)
Remove an arbitrary element from the heap.
Definition: pairing_heap.hpp:220
void pop()
Remove the top element from the heap.
Definition: pairing_heap.hpp:142
void merge(PairingHeap &&other)
Merge this heap with another heap.
Definition: pairing_heap.hpp:192
iterator push(const T &t)
Insert an element into the heap.
Definition: pairing_heap.hpp:114
const T & top()
Returns the top element. The heap must be non-empty.
Definition: pairing_heap.hpp:101
bool empty() const
Returns whether the heap is empty.
Definition: pairing_heap.hpp:98
void decrease_key(iterator it, const T &new_key)
Decrease the value of a given element.
Definition: pairing_heap.hpp:204
iterator emplace(Args &&... args)
Construct a new element in place in the heap.
Definition: pairing_heap.hpp:130
iterator end()
Returns a null-pointer iterator, intended for default value or edge case checking.
Definition: pairing_heap.hpp:107