-
Notifications
You must be signed in to change notification settings - Fork 0
/
MaxFibanocciHeap.java
248 lines (197 loc) · 5.49 KB
/
MaxFibanocciHeap.java
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
import java.util.*;
class MaxFibanocciHeap{
Node max_pointer = null; //This class variable always points to the node with max_value;
int num_nodes = 0; //Keeps track of number of nodes
public void insert(Node node) {
// if the heap is empty, make the new node as max_pointer
if(max_pointer == null) {
max_pointer = node;
node.left = node;
node.right = node;
}
//else add the new node behind max_pointer
else {
node.left = max_pointer.left;
max_pointer.left.right = node;
max_pointer.left = node;
node.right = max_pointer;
if(node.data > max_pointer.data) {
max_pointer = node;
}
}
num_nodes++;
}
public Node removeMax() {
Node max_element = max_pointer;
if(max_pointer == null) {
return null;
}
int num_children = max_pointer.degree;
Node temp;
Node curr_child = max_pointer.child;
//add all max_node's children to top level
while(num_children > 0) {
temp = curr_child.right;
//remove curr_child from children list
curr_child.left.right = curr_child.right;
curr_child.right.left = curr_child.left;
//add curr_child to top level list
curr_child.right = max_pointer.right;
max_pointer.right.left = curr_child;
max_pointer.right = curr_child;
curr_child.left = max_pointer;
//set parent of curr_child to null
curr_child.parent = null;
curr_child = temp;
num_children--;
}
num_nodes--;
//if no nodes remain after delete_max
if(num_nodes == 0) {
max_pointer = null;
return max_element;
}
//remove max_pointer
max_pointer.left.right = max_pointer.right;
max_pointer.right.left = max_pointer.left;
findNextMax();
if(num_nodes > 1) {
pairWiseCombine();
}
max_element.degree = 0;
max_element.parent = null;
max_element.child = null;
max_element.childCutFlag = false;
max_element.right = max_element;
max_element.left = max_element;
return max_element;
}
public void findNextMax() {
max_pointer = max_pointer.right;
Node temp = max_pointer;
Node next_temp;
int max;
max = max_pointer.data;
next_temp = max_pointer.right;
//logic to find the max_element
while(next_temp != temp) {
if(next_temp.data >= max){
max = next_temp.data;
max_pointer = next_temp;
}
next_temp = next_temp.right;
}
}
public void pairWiseCombine() {
int curr_degree;
Node curr_node, exist_node, parent, child, next_node;
int top_num_nodes = 1;
HashMap<Integer, Node> degree_table = new HashMap<>();
curr_node = max_pointer.right;
//calculates number of top level nodes
while(curr_node != max_pointer) {
top_num_nodes++;
curr_node = curr_node.right;
}
curr_node = max_pointer;
//traverse each top level node to perform pair wise combining
while(top_num_nodes > 0) {
next_node = curr_node.right;
curr_degree = curr_node.degree;
parent = curr_node;
//loop until a tree's degree becomes unique
while(true) {
//if no other tree seen till now has curr_degree
if(!degree_table.containsKey(curr_degree)) {
degree_table.put(curr_degree, parent);
break;
}
//get existing node with curr_degree
exist_node = degree_table.get(curr_degree);
//assign the greater of 2 nodes to be combined to parent and the smaller to child
if(exist_node.data >= parent.data) {
child = parent;
parent = exist_node;
}
else
child = exist_node;
//make child node the child of parent
makeChild(parent, child);
//update degree table
degree_table.remove(curr_degree);
//increment degree
curr_degree++;
}
curr_node = next_node;
top_num_nodes--;
}
}
public void makeChild(Node parent, Node child) {
//remove child from root level
child.left.right = child.right;
child.right.left = child.left;
child.parent = parent;
//if parent did not have any child
if(parent.child == null) {
parent.child = child;
child.right = child;
child.left = child;
}
//if parent had children
else {
child.right = parent.child.right;
child.left = parent.child;
parent.child.right = child;
child.right.left = child;
}
//increase degree of parent
parent.degree++;
//mark child's child cut field as false
child.childCutFlag = false;
}
public void increaseKey(Node node, int data) {
//increase data of node by specified amount
node.data = node.data + data;
Node parent = node.parent;
//perform cut if node is not in top level and data becomes greater its parent's data
if(parent != null && node.data > parent.data) {
cut(parent, node);
}
//check if the increased key is greater than max_pointer
if(node.data > max_pointer.data) {
max_pointer = node;
}
}
public void cut(Node parent, Node child) {
parent.degree--;
//update child pointer of parent if necessary
if(parent.degree == 0) {
parent.child = null;
}
else {
if(parent.child == child)
parent.child = child.right;
//remove child from its sibling list
child.left.right = child.right;
child.right.left = child.left;
}
//move child to root list
child.right = max_pointer.right;
child.left = max_pointer;
child.right.left = child;
max_pointer.right = child;
child.parent = null;
//set child's childCutFlag to false
child.childCutFlag = false;
//perform cascading cut if necessary
child = parent;
parent = parent.parent;
if(parent != null) {
if(!child.childCutFlag)
child.childCutFlag = true;
else{
cut(parent, child);
}
}
}
}