26
26
27
27
#include " utils.h"
28
28
29
+ #include " RedBlackTree.cpp"
30
+
29
31
template <typename T>
30
32
class FNode {
31
33
public:
32
34
FNode (T k, FNode<T>* P): key(k), degree(0 ), p(P), child(nullptr ),
33
35
left (nullptr ), right(nullptr ), mark(false ) {}
34
- // FNode<T>* recursive_destruct() {}
36
+ FNode<T>* recursive_destruct () {
37
+ while (child)
38
+ delete DLLRemove (child, child)->recursive_destruct ();
39
+ return this ;
40
+ }
35
41
T key;
36
42
size_t degree;
37
43
FNode<T> *p, *child, *left, *right;
38
44
bool mark;
39
45
};
40
46
47
+ template <typename T>
48
+ class FNodeDeg {
49
+ public:
50
+ FNodeDeg (): data(nullptr ) {}
51
+ FNodeDeg (FNode<T>* d): data(d) {}
52
+ bool operator <(const FNodeDeg& rhs) const {
53
+ return data->degree < rhs.data ->degree ;
54
+ }
55
+ bool operator ==(const FNodeDeg& rhs) const {
56
+ return data->degree == rhs.data ->degree ;
57
+ }
58
+ FNode<T>* data;
59
+ };
60
+
61
+ template <typename T>
62
+ void DLLInsert (FNode<T>*& root, FNode<T>* x) {
63
+ if (root) {
64
+ x->left = root->left ;
65
+ x->left ->right = x;
66
+ x->right = root;
67
+ root->left = x;
68
+ } else {
69
+ root = x;
70
+ root->left = root;
71
+ root->right = root;
72
+ }
73
+ }
74
+
75
+ template <typename T>
76
+ FNode<T>* DLLRemove (FNode<T>*& root, FNode<T>* x) {
77
+ if (root == root->right )
78
+ root = nullptr ;
79
+ else {
80
+ if (root == x)
81
+ root = root->right ;
82
+ x->left ->right = x->right ;
83
+ x->right ->left = x->left ;
84
+ }
85
+ return x;
86
+ }
87
+
41
88
template <typename T>
42
89
class FibHeap {
43
90
public:
@@ -48,18 +95,9 @@ class FibHeap {
48
95
}
49
96
FNode<T>* FibHeapInsert (const T& k) {
50
97
FNode<T>* x = new FNode<T>(k, nullptr );
51
- if (!min) {
52
- x->left = x;
53
- x->right = x;
98
+ DLLInsert (min, x);
99
+ if (x->key < min->key )
54
100
min = x;
55
- } else {
56
- x->left = min->left ;
57
- x->right = min;
58
- min->left = x;
59
- x->left ->right = x;
60
- if (x->key < min->key )
61
- min = x;
62
- }
63
101
n++;
64
102
return x;
65
103
}
@@ -86,7 +124,71 @@ class FibHeap {
86
124
rhs.MakeFibHeap ();
87
125
return H;
88
126
}
89
- // ~FibHeap() { if (min) { delete min->recursive_destruct(); } }
127
+ FNode<T>* FibHeapLink (FNode<T>* x, FNode<T>* y) {
128
+ if (x->key > y->key )
129
+ std::swap (x, y);
130
+ DLLInsert (x->child , y);
131
+ x->degree ++;
132
+ y->mark = false ;
133
+ return x;
134
+ }
135
+ void Consolidate () {
136
+ RedBlackTree<FNodeDeg<T>> A;
137
+ while (min) {
138
+ FNode<T>* x = DLLRemove (min, min);
139
+ while (true ) {
140
+ Node<CData<FNodeDeg<T>>>* Y = A.TreeSearch (FNodeDeg<T>(x));
141
+ if (Y == A.nil )
142
+ break ;
143
+ FNode<T>* y = Y->data .data .data ;
144
+ A.RBDelete (Y);
145
+ x = FibHeapLink (x, y);
146
+ }
147
+ A.RBInsert (FNodeDeg<T>(x));
148
+ }
149
+ for (auto i = A.TreeMinimum (); i != A.nil ; i = A.TreeSuccessor (i)) {
150
+ FNode<T>* x = i->data .data .data ;
151
+ DLLInsert (min, x);
152
+ if (x->key < min->key )
153
+ min = x;
154
+ }
155
+ }
156
+ FNode<T>* FibHeapExtractMin () {
157
+ FNode<T>* z = min;
158
+ if (z) {
159
+ while (z->child )
160
+ DLLInsert (min, DLLRemove (z->child , z->child ));
161
+ DLLRemove (min, z);
162
+ if (min)
163
+ Consolidate ();
164
+ n--;
165
+ }
166
+ return z;
167
+ }
168
+ void print_tree (FNode<T>* x, size_t indent) {
169
+ if (!x) {
170
+ std::cout << std::endl;
171
+ return ;
172
+ }
173
+ std::cout << x->key << ' \t ' ;
174
+ print_tree (x->child , indent + 1 );
175
+ for (FNode<T>* i = x->right ; i != x; i = i->right ) {
176
+ std::cout << std::string (indent, ' \t ' ) << i->key << ' \t ' ;
177
+ print_tree (i->child , indent + 1 );
178
+ }
179
+ }
180
+ void print_tree () {
181
+ std::cout << std::endl;
182
+ if (min)
183
+ print_tree (min, 0 );
184
+ else
185
+ std::cout << " (empty)" << std::endl;
186
+ std::cout << std::endl;
187
+ }
188
+ ~FibHeap () {
189
+ while (min)
190
+ delete DLLRemove (min, min)->recursive_destruct ();
191
+ }
90
192
FNode<T>* min;
91
193
size_t n;
92
194
};
@@ -100,7 +202,8 @@ int main(int argc, char *argv[]) {
100
202
std::cout << " i: insert" << std::endl;
101
203
std::cout << " m: minimum" << std::endl;
102
204
std::cout << " u: union" << std::endl;
103
- // std::cout << "p: print tree" << std::endl;
205
+ std::cout << " e: extract minimum" << std::endl;
206
+ std::cout << " p: print tree" << std::endl;
104
207
std::cout << " q: quit" << std::endl;
105
208
FNode<int >* ptr = nullptr ;
106
209
size_t n = 0 ;
@@ -135,6 +238,18 @@ int main(int argc, char *argv[]) {
135
238
std::cin >> n2;
136
239
*FH = FH->FibHeapUnion (FH_list[n2]);
137
240
break ;
241
+ case ' e' :
242
+ ptr = FH->FibHeapExtractMin ();
243
+ if (ptr) {
244
+ std::cout << " min = " << ptr->key << std::endl;
245
+ delete ptr;
246
+ ptr = FH->min ;
247
+ } else
248
+ std::cout << " empty heap" << std::endl;
249
+ break ;
250
+ case ' p' :
251
+ FH->print_tree ();
252
+ break ;
138
253
case ' q' :
139
254
return 0 ;
140
255
}
0 commit comments