|
24 | 24 | #ifndef FUNC_FibHeap
|
25 | 25 | #define FUNC_FibHeap
|
26 | 26 |
|
| 27 | +#include <exception> |
27 | 28 | #include "utils.h"
|
28 | 29 |
|
29 | 30 | #include "RedBlackTree.cpp"
|
@@ -129,6 +130,7 @@ class FibHeap {
|
129 | 130 | std::swap(x, y);
|
130 | 131 | DLLInsert(x->child, y);
|
131 | 132 | x->degree++;
|
| 133 | + y->p = x; |
132 | 134 | y->mark = false;
|
133 | 135 | return x;
|
134 | 136 | }
|
@@ -156,15 +158,54 @@ class FibHeap {
|
156 | 158 | FNode<T>* FibHeapExtractMin() {
|
157 | 159 | FNode<T>* z = min;
|
158 | 160 | if (z) {
|
159 |
| - while(z->child) |
160 |
| - DLLInsert(min, DLLRemove(z->child, z->child)); |
| 161 | + while(z->child) { |
| 162 | + FNode<T>* c = DLLRemove(z->child, z->child); |
| 163 | + DLLInsert(min, c); |
| 164 | + c->p = nullptr; |
| 165 | + } |
161 | 166 | DLLRemove(min, z);
|
162 | 167 | if (min)
|
163 | 168 | Consolidate();
|
164 | 169 | n--;
|
165 | 170 | }
|
166 | 171 | return z;
|
167 | 172 | }
|
| 173 | + void Cut(FNode<T>* x, FNode<T>* y) { |
| 174 | + DLLRemove(y->child, x); |
| 175 | + y->degree--; |
| 176 | + DLLInsert(min, x); |
| 177 | + x->p = nullptr; |
| 178 | + x->mark = false; |
| 179 | + } |
| 180 | + void CascadingCut(FNode<T>* y) { |
| 181 | + FNode<T>* z = y->p; |
| 182 | + if (z) { |
| 183 | + if (y->mark) { |
| 184 | + Cut(y, z); |
| 185 | + CascadingCut(z); |
| 186 | + } else |
| 187 | + y->mark = true; |
| 188 | + } |
| 189 | + } |
| 190 | + void FibHeapDecreaseKey(FNode<T>* x, T k) { |
| 191 | + if (k > x->key) |
| 192 | + throw std::invalid_argument("new key > current key"); |
| 193 | + x->key = k; |
| 194 | + FNode<T>* y = x->p; |
| 195 | + if (y && x->key < y->key) { |
| 196 | + Cut(x, y); |
| 197 | + CascadingCut(y); |
| 198 | + } |
| 199 | + if (x->key < min->key) |
| 200 | + min = x; |
| 201 | + } |
| 202 | + void FibHeapDelete(FNode<T>* x) { |
| 203 | + T minf = min->key - 1; |
| 204 | + if (minf >= min->key) |
| 205 | + throw std::invalid_argument("cannot create minf"); |
| 206 | + FibHeapDecreaseKey(x, minf); |
| 207 | + FibHeapExtractMin(); |
| 208 | + } |
168 | 209 | void print_tree(FNode<T>* x, size_t indent) {
|
169 | 210 | if (!x) {
|
170 | 211 | std::cout << std::endl;
|
@@ -203,14 +244,22 @@ int main(int argc, char *argv[]) {
|
203 | 244 | std::cout << "m: minimum" << std::endl;
|
204 | 245 | std::cout << "u: union" << std::endl;
|
205 | 246 | std::cout << "e: extract minimum" << std::endl;
|
206 |
| - std::cout << "p: print tree" << std::endl; |
| 247 | + std::cout << "d: decrease key" << std::endl; |
| 248 | + std::cout << "D: delete" << std::endl; |
| 249 | + std::cout << "p: parent" << std::endl; |
| 250 | + std::cout << "c: child" << std::endl; |
| 251 | + std::cout << "l: left" << std::endl; |
| 252 | + std::cout << "r: right" << std::endl; |
| 253 | + std::cout << "P: print tree" << std::endl; |
207 | 254 | std::cout << "q: quit" << std::endl;
|
208 | 255 | FNode<int>* ptr = nullptr;
|
209 | 256 | size_t n = 0;
|
210 | 257 | while (true) {
|
211 | 258 | char c; int x; size_t n2;
|
212 | 259 | std::cout << "n = " << n << std::endl;
|
213 | 260 | std::cout << "ptr = " << pptr(ptr) << std::endl;
|
| 261 | + if (ptr) |
| 262 | + std::cout << " = " << ptr->key << std::endl; |
214 | 263 | std::cout << ">> ";
|
215 | 264 | if (!(std::cin >> c)) {
|
216 | 265 | std::cout << std::endl;
|
@@ -247,7 +296,28 @@ int main(int argc, char *argv[]) {
|
247 | 296 | } else
|
248 | 297 | std::cout << "empty heap" << std::endl;
|
249 | 298 | break;
|
| 299 | + case 'd': |
| 300 | + std::cout << "x = "; |
| 301 | + std::cin >> x; |
| 302 | + FH->FibHeapDecreaseKey(ptr, x); |
| 303 | + break; |
| 304 | + case 'D': |
| 305 | + FH->FibHeapDelete(ptr); |
| 306 | + ptr = FH->min; |
| 307 | + break; |
250 | 308 | case 'p':
|
| 309 | + ptr = ptr->p; |
| 310 | + break; |
| 311 | + case 'c': |
| 312 | + ptr = ptr->child; |
| 313 | + break; |
| 314 | + case 'l': |
| 315 | + ptr = ptr->left; |
| 316 | + break; |
| 317 | + case 'r': |
| 318 | + ptr = ptr->right; |
| 319 | + break; |
| 320 | + case 'P': |
251 | 321 | FH->print_tree();
|
252 | 322 | break;
|
253 | 323 | case 'q':
|
|
0 commit comments