10
10
*/
11
11
public class LeonardoHeap <T extends Comparable <T >> {
12
12
13
- private int leonardoLevelTracker ;
14
- private int leonardoHeapSize ;
15
- private final List <T > leonardoHeap ;
13
+ private int levelTracker = 0 ;
14
+ private final List <T > heap = new ArrayList <T >();
16
15
17
16
public LeonardoHeap () {
18
- this .leonardoHeap = new ArrayList <T >();
19
- this .leonardoLevelTracker = 0 ;
20
- this .leonardoHeapSize = 0 ;
21
17
}
22
18
23
- public int getHeapsize () {
24
- return this .leonardoHeapSize ;
25
- }
26
-
27
- private void decreaseLeonardoLevelTracker () {
19
+ private void decreaseLevelTracker () {
28
20
int lastTreeLevel = getRightMostTree ();
29
- leonardoLevelTracker = SingleBitOperations .clearBit (leonardoLevelTracker , lastTreeLevel );
21
+ levelTracker = SingleBitOperations .clearBit (levelTracker , lastTreeLevel );
30
22
if (lastTreeLevel != 0 && lastTreeLevel != 1 ) {
31
- leonardoLevelTracker = SingleBitOperations .setBit (leonardoLevelTracker , lastTreeLevel - 1 );
32
- leonardoLevelTracker = SingleBitOperations .setBit (leonardoLevelTracker , lastTreeLevel - 2 );
23
+ levelTracker = SingleBitOperations .setBit (levelTracker , lastTreeLevel - 1 );
24
+ levelTracker = SingleBitOperations .setBit (levelTracker , lastTreeLevel - 2 );
33
25
}
34
26
}
35
27
36
- private void increaseLeonardoLevelTracker () {
37
- ArrayList <Integer > consecutiveTreeIndices = findConsecutiveLeonardoTreeIndices ( leonardoLevelTracker );
28
+ private void increaseLevelTracker () {
29
+ ArrayList <Integer > consecutiveTreeIndices = findConsecutiveTreeIndices ( levelTracker );
38
30
if (consecutiveTreeIndices .get (0 ) != -1 ) {
39
31
// if 0th or 1st index is -1 that implies there are no concequtive trees
40
- leonardoLevelTracker = SingleBitOperations .clearBit (leonardoLevelTracker , consecutiveTreeIndices .get (0 ));
41
- leonardoLevelTracker = SingleBitOperations .clearBit (leonardoLevelTracker , consecutiveTreeIndices .get (1 ));
42
- leonardoLevelTracker = SingleBitOperations .setBit (leonardoLevelTracker , consecutiveTreeIndices .get (1 ) + 1 );
43
- } else if ((leonardoLevelTracker & 2 ) == 0 ) {
44
- leonardoLevelTracker = SingleBitOperations .setBit (leonardoLevelTracker , 1 );
32
+ levelTracker = SingleBitOperations .clearBit (levelTracker , consecutiveTreeIndices .get (0 ));
33
+ levelTracker = SingleBitOperations .clearBit (levelTracker , consecutiveTreeIndices .get (1 ));
34
+ levelTracker = SingleBitOperations .setBit (levelTracker , consecutiveTreeIndices .get (1 ) + 1 );
35
+ } else if ((levelTracker & 2 ) == 0 ) {
36
+ levelTracker = SingleBitOperations .setBit (levelTracker , 1 );
45
37
} else {
46
- leonardoLevelTracker = SingleBitOperations .setBit (leonardoLevelTracker , 0 );
38
+ levelTracker = SingleBitOperations .setBit (levelTracker , 0 );
47
39
}
48
40
}
49
41
50
- private void decreaseHeapSize () {
51
- this .leonardoHeapSize --;
52
- }
53
-
54
- private void increaseHeapSize () {
55
- this .leonardoHeapSize ++;
56
- }
57
-
58
- private void maxHeapifyLeonardoTree (int rootNodeIndex , int currentLeonardoLevel ) {
42
+ private void maxHeapifyTree (int rootNodeIndex , int currentLevel ) {
59
43
// A leonardo tree of level n is just 1 node(the root) plus the leonardo tree of n-1 level(left child) plus leonardo tree of n-2 level(right child)
60
44
// To maxheapify a leonardo tree we need to compare the current root and roots of it's left and right subtree
61
- // We recursively hepify the left and right subtrees using the currentLeonardoLevel
45
+ // We recursively hepify the left and right subtrees using the currentLevel
62
46
63
47
// BASE CASE
64
- if (currentLeonardoLevel == 0 || currentLeonardoLevel == 1 ) {
48
+ if (currentLevel == 0 || currentLevel == 1 ) {
65
49
return ; // Trees with one node are in already max-heapified.
66
50
}
67
51
68
52
int currentRootNodeIndex = rootNodeIndex ;
69
53
int rightChildIndex = rootNodeIndex - 1 ;
70
- int leftChildIndex = rootNodeIndex - LeonardoNumber .leonardoNumber (currentLeonardoLevel - 2 ) - 1 ;
54
+ int leftChildIndex = rootNodeIndex - LeonardoNumber .leonardoNumber (currentLevel - 2 ) - 1 ;
71
55
int childIndexForSwap = -1 ;
72
56
73
- if (leonardoHeap .get (rightChildIndex ).compareTo (leonardoHeap .get (leftChildIndex )) >= 0 ) {
57
+ if (heap .get (rightChildIndex ).compareTo (heap .get (leftChildIndex )) >= 0 ) {
74
58
childIndexForSwap = rightChildIndex ;
75
59
} else {
76
60
childIndexForSwap = leftChildIndex ;
77
61
}
78
62
79
- if (leonardoHeap .get (childIndexForSwap ).compareTo (leonardoHeap .get (currentRootNodeIndex )) > 0 ) {
63
+ if (heap .get (childIndexForSwap ).compareTo (heap .get (currentRootNodeIndex )) > 0 ) {
80
64
swap (currentRootNodeIndex , childIndexForSwap );
81
65
if (childIndexForSwap == rightChildIndex ) {
82
- maxHeapifyLeonardoTree (rightChildIndex , currentLeonardoLevel - 2 );
66
+ maxHeapifyTree (rightChildIndex , currentLevel - 2 );
83
67
} else { // swap happened with the left child
84
- maxHeapifyLeonardoTree (leftChildIndex , currentLeonardoLevel - 1 );
68
+ maxHeapifyTree (leftChildIndex , currentLevel - 1 );
85
69
}
86
70
}
87
71
}
88
72
89
73
private void shiftRootAndRestoreHeap () {
90
74
91
- if (getHeapsize () == 0 ) {
75
+ if (heap . size () == 0 ) {
92
76
return ;
93
77
}
94
78
95
- Integer [] currentLeonardoTreeLevels = findAllLeonardoTreeIndices ();
79
+ Integer [] currentTreeLevels = findAllTreeIndices ();
96
80
int previousTreeSizeCumulative = 0 ;
97
81
ArrayList <Integer > rootNodeIndices = new ArrayList <Integer >();
98
82
99
83
// The number of roots are going to be same the the number of levels
100
- // iterate over the currentLeonardoTreeLevels and get roots
84
+ // iterate over the currentTreeLevels and get roots
101
85
102
- for (int i = 0 ; i < currentLeonardoTreeLevels .length ; i ++) {
103
- rootNodeIndices .add (previousTreeSizeCumulative + LeonardoNumber .leonardoNumber (currentLeonardoTreeLevels [i ]) - 1 );
104
- previousTreeSizeCumulative = previousTreeSizeCumulative + LeonardoNumber .leonardoNumber (currentLeonardoTreeLevels [i ]);
86
+ for (int i = 0 ; i < currentTreeLevels .length ; i ++) {
87
+ rootNodeIndices .add (previousTreeSizeCumulative + LeonardoNumber .leonardoNumber (currentTreeLevels [i ]) - 1 );
88
+ previousTreeSizeCumulative = previousTreeSizeCumulative + LeonardoNumber .leonardoNumber (currentTreeLevels [i ]);
105
89
}
106
90
107
91
int rootNodeIndexForHeapify = rootNodeIndices .getLast ();
108
- int leonardoTreeLevelforHeapify = currentLeonardoTreeLevels [ currentLeonardoTreeLevels .length - 1 ];
92
+ int treeLevelforHeapify = currentTreeLevels [ currentTreeLevels .length - 1 ];
109
93
boolean swaped = false ;
110
94
111
95
for (int i = 1 ; i < rootNodeIndices .size (); i ++) {
112
96
113
97
int currentRootNodeIndex = rootNodeIndices .get (i );
114
98
int prevRootNodeIndex = rootNodeIndices .get (i - 1 );
115
99
int j = i ;
116
- while (leonardoHeap .get (prevRootNodeIndex ).compareTo (leonardoHeap .get (currentRootNodeIndex )) > 0 ) {
117
- int currentLeonardoLevel = currentLeonardoTreeLevels [j ];
118
- if (currentLeonardoLevel > 1 ) {
100
+ while (heap .get (prevRootNodeIndex ).compareTo (heap .get (currentRootNodeIndex )) > 0 ) {
101
+ int currentLevel = currentTreeLevels [j ];
102
+ if (currentLevel > 1 ) {
119
103
// compare child and swap
120
104
121
105
int indexOfRightChild = rootNodeIndices .get (j ) - 1 ; // right child is of level n-2
122
- int indexOfLeftChild = rootNodeIndices .get (j ) - 1 - LeonardoNumber .leonardoNumber (currentLeonardoLevel - 2 );
123
- if (leonardoHeap .get (prevRootNodeIndex ).compareTo (leonardoHeap .get (indexOfRightChild )) > 0 && leonardoHeap .get (prevRootNodeIndex ).compareTo (leonardoHeap .get (indexOfLeftChild )) > 0 ) {
106
+ int indexOfLeftChild = rootNodeIndices .get (j ) - 1 - LeonardoNumber .leonardoNumber (currentLevel - 2 );
107
+ if (heap .get (prevRootNodeIndex ).compareTo (heap .get (indexOfRightChild )) > 0 && heap .get (prevRootNodeIndex ).compareTo (heap .get (indexOfLeftChild )) > 0 ) {
124
108
swap (prevRootNodeIndex , currentRootNodeIndex );
125
109
rootNodeIndexForHeapify = prevRootNodeIndex ;
126
- leonardoTreeLevelforHeapify = currentLeonardoTreeLevels [j - 1 ];
110
+ treeLevelforHeapify = currentTreeLevels [j - 1 ];
127
111
swaped = true ;
128
112
} else {
129
- maxHeapifyLeonardoTree (currentRootNodeIndex , currentLeonardoLevel );
113
+ maxHeapifyTree (currentRootNodeIndex , currentLevel );
130
114
swaped = false ;
131
115
}
132
116
} else {
133
117
swap (prevRootNodeIndex , currentRootNodeIndex );
134
118
rootNodeIndexForHeapify = prevRootNodeIndex ;
135
- leonardoTreeLevelforHeapify = currentLeonardoTreeLevels [j - 1 ];
119
+ treeLevelforHeapify = currentTreeLevels [j - 1 ];
136
120
swaped = true ;
137
121
}
138
122
j = j - 1 ;
@@ -146,17 +130,17 @@ private void shiftRootAndRestoreHeap() {
146
130
}
147
131
148
132
if (swaped ) {
149
- maxHeapifyLeonardoTree (rootNodeIndexForHeapify , leonardoTreeLevelforHeapify );
133
+ maxHeapifyTree (rootNodeIndexForHeapify , treeLevelforHeapify );
150
134
swaped = false ;
151
135
}
152
136
}
153
137
154
- maxHeapifyLeonardoTree (rootNodeIndexForHeapify , leonardoTreeLevelforHeapify ); // In case of insert and no swap.
138
+ maxHeapifyTree (rootNodeIndexForHeapify , treeLevelforHeapify ); // In case of insert and no swap.
155
139
}
156
140
157
141
private int getRightMostTree () {
158
142
// Isolate the rightmost set bit
159
- int isolatedBit = leonardoLevelTracker & -leonardoLevelTracker ;
143
+ int isolatedBit = levelTracker & -levelTracker ;
160
144
int position = 0 ;
161
145
162
146
while (isolatedBit > 1 ) {
@@ -167,7 +151,7 @@ private int getRightMostTree() {
167
151
return position ;
168
152
}
169
153
170
- private static ArrayList <Integer > findConsecutiveLeonardoTreeIndices (int num ) {
154
+ private static ArrayList <Integer > findConsecutiveTreeIndices (int num ) {
171
155
int prevOneIndex = -1 ;
172
156
int currentLevel ;
173
157
@@ -192,32 +176,30 @@ private static ArrayList<Integer> findConsecutiveLeonardoTreeIndices(int num) {
192
176
}
193
177
194
178
private void swap (int i , int j ) {
195
- T temp = leonardoHeap .get (i );
196
- leonardoHeap .set (i , leonardoHeap .get (j ));
197
- leonardoHeap .set (j , temp );
179
+ T temp = heap .get (i );
180
+ heap .set (i , heap .get (j ));
181
+ heap .set (j , temp );
198
182
}
199
183
200
- private Integer [] findAllLeonardoTreeIndices () {
184
+ private Integer [] findAllTreeIndices () {
201
185
List <Integer > setBitIndexes = new ArrayList <>();
202
186
for (int i = Integer .SIZE - 1 ; i >= 0 ; i --) {
203
- if ((leonardoLevelTracker & (1 << i )) != 0 ) {
187
+ if ((levelTracker & (1 << i )) != 0 ) {
204
188
setBitIndexes .add (i );
205
189
}
206
190
}
207
191
return setBitIndexes .toArray (new Integer [0 ]);
208
192
}
209
193
210
194
public void addElement (T element ) {
211
- increaseLeonardoLevelTracker ();
212
- leonardoHeap .add (element );
213
- increaseHeapSize ();
195
+ increaseLevelTracker ();
196
+ heap .add (element );
214
197
shiftRootAndRestoreHeap ();
215
198
}
216
199
217
200
public T removeElement () {
218
- decreaseLeonardoLevelTracker ();
219
- decreaseHeapSize ();
220
- T element = leonardoHeap .removeLast ();
201
+ decreaseLevelTracker ();
202
+ T element = heap .removeLast ();
221
203
shiftRootAndRestoreHeap ();
222
204
223
205
return element ;
0 commit comments