1
1
package com .thealgorithms .datastructures .heaps ;
2
2
3
- import com .thealgorithms .bitmanipulation .SingleBitOperations ;
4
- import com .thealgorithms .maths .LeonardoNumber ;
5
3
import java .util .ArrayList ;
4
+ import java .util .Collections ;
6
5
import java .util .List ;
7
6
7
+ import com .thealgorithms .bitmanipulation .SingleBitOperations ;
8
+ import com .thealgorithms .maths .LeonardoNumber ;
9
+
8
10
/**
9
11
* Wikipedia: https://en.wikipedia.org/wiki/Smoothsort
10
12
*/
@@ -17,7 +19,7 @@ public LeonardoHeap() {
17
19
}
18
20
19
21
private void decreaseLevelTracker () {
20
- int lastTreeLevel = getRightMostTree ();
22
+ final int lastTreeLevel = getRightMostTree ();
21
23
levelTracker = SingleBitOperations .clearBit (levelTracker , lastTreeLevel );
22
24
if (lastTreeLevel != 0 && lastTreeLevel != 1 ) {
23
25
levelTracker = SingleBitOperations .setBit (levelTracker , lastTreeLevel - 1 );
@@ -26,7 +28,7 @@ private void decreaseLevelTracker() {
26
28
}
27
29
28
30
private void increaseLevelTracker () {
29
- ArrayList <Integer > consecutiveTreeIndices = LeonardoHeapHelper . findConsecutiveTreeIndices (levelTracker );
31
+ final ArrayList <Integer > consecutiveTreeIndices = findConsecutiveTreeIndices (levelTracker );
30
32
if (consecutiveTreeIndices .get (0 ) != -1 ) {
31
33
// if 0th or 1st index is -1 that implies there are no concequtive trees
32
34
levelTracker = SingleBitOperations .clearBit (levelTracker , consecutiveTreeIndices .get (0 ));
@@ -49,16 +51,10 @@ private void maxHeapifyTree(int rootNodeIndex, int currentLevel) {
49
51
return ; // Trees with one node are in already max-heapified.
50
52
}
51
53
52
- int currentRootNodeIndex = rootNodeIndex ;
53
- int rightChildIndex = rootNodeIndex - 1 ;
54
- int leftChildIndex = rootNodeIndex - LeonardoNumber .leonardoNumber (currentLevel - 2 ) - 1 ;
55
- int childIndexForSwap = -1 ;
56
-
57
- if (heap .get (rightChildIndex ).compareTo (heap .get (leftChildIndex )) >= 0 ) {
58
- childIndexForSwap = rightChildIndex ;
59
- } else {
60
- childIndexForSwap = leftChildIndex ;
61
- }
54
+ final int currentRootNodeIndex = rootNodeIndex ;
55
+ final int rightChildIndex = rootNodeIndex - 1 ;
56
+ final int leftChildIndex = rootNodeIndex - LeonardoNumber .leonardoNumber (currentLevel - 2 ) - 1 ;
57
+ final int childIndexForSwap = (heap .get (rightChildIndex ).compareTo (heap .get (leftChildIndex )) >= 0 ) ? rightChildIndex : leftChildIndex ;
62
58
63
59
if (heap .get (childIndexForSwap ).compareTo (heap .get (currentRootNodeIndex )) > 0 ) {
64
60
swap (currentRootNodeIndex , childIndexForSwap );
@@ -76,7 +72,7 @@ private void shiftRootAndRestoreHeap() {
76
72
return ;
77
73
}
78
74
79
- Integer [] currentTreeLevels = LeonardoHeapHelper . findAllTreeIndices (levelTracker );
75
+ final Integer [] currentTreeLevels = findAllTreeIndices (levelTracker );
80
76
int previousTreeSizeCumulative = 0 ;
81
77
ArrayList <Integer > rootNodeIndices = new ArrayList <Integer >();
82
78
@@ -90,34 +86,35 @@ private void shiftRootAndRestoreHeap() {
90
86
91
87
int rootNodeIndexForHeapify = rootNodeIndices .getLast ();
92
88
int treeLevelforHeapify = currentTreeLevels [currentTreeLevels .length - 1 ];
93
- boolean swaped = false ;
94
89
95
90
for (int i = 1 ; i < rootNodeIndices .size (); i ++) {
96
91
97
92
int currentRootNodeIndex = rootNodeIndices .get (i );
98
93
int prevRootNodeIndex = rootNodeIndices .get (i - 1 );
99
94
int j = i ;
95
+ boolean swapped = false ;
96
+
100
97
while (heap .get (prevRootNodeIndex ).compareTo (heap .get (currentRootNodeIndex )) > 0 ) {
101
- int currentLevel = currentTreeLevels [j ];
98
+ final int currentLevel = currentTreeLevels [j ];
102
99
if (currentLevel > 1 ) {
103
100
// compare child and swap
104
101
105
- int indexOfRightChild = rootNodeIndices .get (j ) - 1 ; // right child is of level n-2
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 ) {
102
+ final int rightChildIndex = rootNodeIndices .get (j ) - 1 ; // right child is of level n-2
103
+ final int leftChildIndex = rootNodeIndices .get (j ) - 1 - LeonardoNumber .leonardoNumber (currentLevel - 2 );
104
+ if (heap .get (prevRootNodeIndex ).compareTo (heap .get (rightChildIndex )) > 0 && heap .get (prevRootNodeIndex ).compareTo (heap .get (leftChildIndex )) > 0 ) {
108
105
swap (prevRootNodeIndex , currentRootNodeIndex );
109
106
rootNodeIndexForHeapify = prevRootNodeIndex ;
110
107
treeLevelforHeapify = currentTreeLevels [j - 1 ];
111
- swaped = true ;
108
+ swapped = true ;
112
109
} else {
113
110
maxHeapifyTree (currentRootNodeIndex , currentLevel );
114
- swaped = false ;
111
+ swapped = false ;
115
112
}
116
113
} else {
117
114
swap (prevRootNodeIndex , currentRootNodeIndex );
118
115
rootNodeIndexForHeapify = prevRootNodeIndex ;
119
116
treeLevelforHeapify = currentTreeLevels [j - 1 ];
120
- swaped = true ;
117
+ swapped = true ;
121
118
}
122
119
j = j - 1 ;
123
120
if (j > 0 ) {
@@ -129,9 +126,8 @@ private void shiftRootAndRestoreHeap() {
129
126
}
130
127
}
131
128
132
- if (swaped ) {
129
+ if (swapped ) {
133
130
maxHeapifyTree (rootNodeIndexForHeapify , treeLevelforHeapify );
134
- swaped = false ;
135
131
}
136
132
}
137
133
@@ -152,9 +148,7 @@ private int getRightMostTree() {
152
148
}
153
149
154
150
private void swap (int i , int j ) {
155
- T temp = heap .get (i );
156
- heap .set (i , heap .get (j ));
157
- heap .set (j , temp );
151
+ Collections .swap (heap , i , j );
158
152
}
159
153
160
154
public void addElement (T element ) {
@@ -165,9 +159,43 @@ public void addElement(T element) {
165
159
166
160
public T removeElement () {
167
161
decreaseLevelTracker ();
168
- T element = heap .removeLast ();
162
+ final T element = heap .removeLast ();
169
163
shiftRootAndRestoreHeap ();
170
164
171
165
return element ;
172
166
}
167
+
168
+ private static ArrayList <Integer > findConsecutiveTreeIndices (int num ) {
169
+ int prevOneIndex = -1 ;
170
+ int currentLevel = 0 ;
171
+
172
+ ArrayList <Integer > answer = new ArrayList <Integer >();
173
+ answer .add (-1 );
174
+ answer .add (-1 );
175
+
176
+ for (int i = 0 ; num > 0 ; i ++) {
177
+ currentLevel = num & 1 ;
178
+ if (currentLevel == 1 ) {
179
+ if (prevOneIndex != -1 ) {
180
+ answer .set (0 , prevOneIndex );
181
+ answer .set (1 , i );
182
+ }
183
+ prevOneIndex = i ;
184
+ } else {
185
+ prevOneIndex = -1 ;
186
+ }
187
+ num >>>= 1 ;
188
+ }
189
+ return answer ;
190
+ }
191
+
192
+ private static Integer [] findAllTreeIndices (int num ) {
193
+ List <Integer > setBitIndexes = new ArrayList <>();
194
+ for (int i = Integer .SIZE - 1 ; i >= 0 ; i --) {
195
+ if ((num & (1 << i )) != 0 ) {
196
+ setBitIndexes .add (i );
197
+ }
198
+ }
199
+ return setBitIndexes .toArray (new Integer [0 ]);
200
+ }
173
201
}
0 commit comments