-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpairing_heap_priqueue.h
127 lines (93 loc) · 2.99 KB
/
pairing_heap_priqueue.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#ifndef PAIRING_HEAP_PRIQUEUE
#define PAIRING_HEAP_PRIQUEUE
#include <cassert>
#include <stack>
template <typename T>
struct heap_node {
const T key;
heap_node<T> * left_child = nullptr;
heap_node<T> * next_sibling = nullptr;
heap_node(const T key) : key(key) {}
void add_child(heap_node<T> *& node) {
if (left_child!=nullptr){
std::swap(node->next_sibling,left_child);
std::swap(left_child,node);
} else {
std::swap(left_child,node);
}
}
};
template <typename T>
struct two_pass_ret {
heap_node<T> * merge_node;
heap_node<T> * new_node;
two_pass_ret(heap_node<T> * merge_node,heap_node<T> * new_node) : merge_node(merge_node),new_node(new_node) {}
};
template <typename T>
class pairing_heap_priqueue {
private:
typedef T key_type;
heap_node<key_type> * root = nullptr;
size_t total_num = 0;
heap_node<T> * insert(heap_node<T> * node, const T key){
auto * node_ptr = new heap_node(key);
return merge(node, node_ptr);
}
inline heap_node<T> * & merge(heap_node<T> *&A, heap_node<T> *&B) {
// If any of the two-nodes is None
// then return the not None node
if(A == nullptr)
return B;
if(B == nullptr)
return A;
// To maintain the min heap condition compare
// the nodes and node with minimum value become
// parent of the other node
if(A->key < B->key) {
A->add_child(B);
return A;
}
B->add_child(A);
return B;
}
heap_node<T> * erase(heap_node<T> * & node) {
heap_node<T> * cur_node = node->left_child;
heap_node<T> * merge_node = nullptr;
while(true) {
if(cur_node == nullptr || cur_node->next_sibling == nullptr)
break;
cur_node = two_pass_merge(merge_node,cur_node);
}
delete node; // remove node
return merge(cur_node,merge_node); // return node
}
inline heap_node<T> * two_pass_merge(heap_node<T> *& merge_node, heap_node<T> *& node) {
auto B = node->next_sibling;
auto new_node = node->next_sibling->next_sibling;
node->next_sibling->next_sibling = nullptr;
node->next_sibling = nullptr;
merge_node = merge(merge_node,merge(node, B));
return new_node;
}
public:
size_t size(void) const {
return total_num;
}
bool empty(void) const {
return total_num == 0;
}
void push(const key_type key) {
root = insert(root,key);
total_num++;
}
void pop(void) {
assert(!empty());
root = erase(root);
total_num--;
}
const T& top(void) const {
assert(!empty());
return root->key;
}
};
#endif //PAIRING_HEAP_PRIQUEUE