Skip to content

Commit 066fb49

Browse files
committed
支持插入和抽取最小元素的斐波那契堆
1 parent fe26e96 commit 066fb49

File tree

1 file changed

+194
-0
lines changed

1 file changed

+194
-0
lines changed

Fibonacci-Heap.cpp

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
1+
// Algorithm: Fibonacci Heap
2+
3+
#include <cstdio>
4+
#include <cstring>
5+
#include <algorithm>
6+
7+
#define NIL 0
8+
#define MAX_HEAP_SIZE 100010
9+
10+
using namespace std;
11+
12+
class FibonacciHeap
13+
{
14+
private:
15+
struct node
16+
{
17+
node *child, *parent, *left, *right;
18+
int key, degree;
19+
bool mark;
20+
node(int _key) : child(NIL), parent(NIL), left(NIL), right(NIL), key(_key), degree(0), mark(false) { }
21+
};
22+
23+
node *min;
24+
size_t heap_size;
25+
26+
void _M_insert_to(node *v, node *u);
27+
void _M_insert_to_root_list(node *u);
28+
void _M_remove_from_root_list(node *u);
29+
void _M_link(node *v, node *u);
30+
void _M_consolidate();
31+
32+
public:
33+
FibonacciHeap();
34+
void insert(int key);
35+
int extract_min();
36+
};
37+
38+
void FibonacciHeap::_M_insert_to(node *v, node *u)
39+
{
40+
v->right = u->right;
41+
v->left = u;
42+
u->right->left = v;
43+
u->right = v;
44+
}
45+
46+
void FibonacciHeap::_M_insert_to_root_list(node *u)
47+
{
48+
_M_insert_to(u, min);
49+
}
50+
51+
void FibonacciHeap::_M_remove_from_root_list(node *u)
52+
{
53+
u->left->right = u->right;
54+
u->right->left = u->left;
55+
}
56+
57+
void FibonacciHeap::_M_link(node *v, node *u)
58+
{
59+
_M_remove_from_root_list(v);
60+
if (u->child == NIL)
61+
{
62+
u->child = v;
63+
v->parent = u;
64+
v->left = v->right = v;
65+
}
66+
else
67+
{
68+
_M_insert_to(v, u->child);
69+
v->parent = u;
70+
}
71+
}
72+
73+
void FibonacciHeap::_M_consolidate()
74+
{
75+
static node *root_list[MAX_HEAP_SIZE];
76+
node *first = min;
77+
node *u = first;
78+
int cnt = 0;
79+
do
80+
{
81+
root_list[cnt++] = u;
82+
u = u->right;
83+
} while (u != first);
84+
node *list[50];
85+
memset(list, 0, sizeof(list));
86+
for (int i = 0; i < cnt; i++)
87+
{
88+
node *x = root_list[i];
89+
while (list[x->degree] != NIL)
90+
{
91+
node *y = list[x->degree];
92+
if (x->key > y->key) swap(x, y);
93+
_M_link(y, x);
94+
list[x->degree++] = NIL;
95+
}
96+
list[x->degree] = x;
97+
}
98+
min = NIL;
99+
for (int i = 0; i < 50; i++)
100+
{
101+
if (list[i] != NIL)
102+
{
103+
if (min == NIL)
104+
{
105+
min = list[i];
106+
list[i]->left = list[i]->right = list[i];
107+
}
108+
else
109+
{
110+
_M_insert_to_root_list(list[i]);
111+
if (list[i]->key < min->key) min = list[i];
112+
}
113+
}
114+
}
115+
}
116+
117+
FibonacciHeap::FibonacciHeap() : min(NIL), heap_size(0) { }
118+
119+
void FibonacciHeap::insert(int key)
120+
{
121+
if (min == NIL)
122+
{
123+
min = new node(key);
124+
min->left = min->right = min;
125+
}
126+
else
127+
{
128+
node *u = new node(key);
129+
_M_insert_to_root_list(u);
130+
if (key < min->key) min = u;
131+
}
132+
heap_size++;
133+
}
134+
135+
int FibonacciHeap::extract_min()
136+
{
137+
int res = min->key;
138+
if (min != NIL)
139+
{
140+
if (heap_size == 1)
141+
{
142+
min = NIL;
143+
}
144+
else
145+
{
146+
if (min->child != NIL)
147+
{
148+
static node *child_list[MAX_HEAP_SIZE];
149+
node *first = min->child;
150+
node *u = first;
151+
int cnt = 0;
152+
do
153+
{
154+
child_list[cnt++] = u;
155+
u = u->right;
156+
} while (u != first);
157+
for (int i = 0; i < cnt; i++)
158+
{
159+
_M_insert_to_root_list(child_list[i]);
160+
}
161+
}
162+
_M_remove_from_root_list(min);
163+
min = min->right;
164+
_M_consolidate();
165+
}
166+
}
167+
heap_size--;
168+
return res;
169+
}
170+
171+
int main()
172+
{
173+
FibonacciHeap H;
174+
char op[10];
175+
int x;
176+
while (true)
177+
{
178+
scanf("%s", op);
179+
if (strcmp(op, "push") == 0)
180+
{
181+
scanf("%d", &x);
182+
H.insert(x);
183+
}
184+
else if (strcmp(op, "pop") == 0)
185+
{
186+
printf("%d\n", H.extract_min());
187+
}
188+
else
189+
{
190+
printf("Command not found.\n");
191+
}
192+
}
193+
return 0;
194+
}

0 commit comments

Comments
 (0)