1
+ package src .main .com .java .sorts ;
2
+
3
+ import java .util .ArrayList ;
4
+ import java .util .Arrays ;
5
+ import java .util .List ;
6
+
7
+ import static src .main .com .java .sorts .SortUtils .less ;
8
+ import static src .main .com .java .sorts .SortUtils .swap ;
9
+
10
+ public class HeapSort {
11
+
12
+
13
+ private static class Heap <T extends Comparable <T >> {
14
+ /**
15
+ * Array to store heap
16
+ */
17
+ private T [] heap ;
18
+
19
+ /**
20
+ * Constructor
21
+ *
22
+ * @param heap array of unordered integers
23
+ */
24
+ Heap (T [] heap ) {
25
+ this .heap = heap ;
26
+ }
27
+
28
+ /**
29
+ * Heapifies subtree from top as root to last as last child
30
+ *
31
+ * @param rootIndex index of root
32
+ * @param lastChild index of last child
33
+ */
34
+ private void heapSubtree (int rootIndex , int lastChild ) {
35
+ int leftIndex = rootIndex * 2 + 1 ;
36
+ int rightIndex = rootIndex * 2 + 2 ;
37
+ T root = heap [rootIndex ];
38
+ if (rightIndex <= lastChild ) {
39
+ // if has right and left children
40
+ T left = heap [leftIndex ];
41
+ T right = heap [rightIndex ];
42
+ if (less (left , right ) && less (left , root )) {
43
+ swap (heap , leftIndex , rootIndex );
44
+ heapSubtree (leftIndex , lastChild );
45
+ } else if (less (right , root )) {
46
+ swap (heap , rightIndex , rootIndex );
47
+ heapSubtree (rightIndex , lastChild );
48
+ }
49
+ } else if (leftIndex <= lastChild ) {
50
+ // if no right child, but has left child
51
+ T left = heap [leftIndex ];
52
+ if (less (left , root )) {
53
+ swap (heap , leftIndex , rootIndex );
54
+ heapSubtree (leftIndex , lastChild );
55
+ }
56
+ }
57
+ }
58
+
59
+
60
+ /**
61
+ * Makes heap with root as root
62
+ *
63
+ * @param root index of root of heap
64
+ */
65
+ private void makeMinHeap (int root ) {
66
+ int leftIndex = root * 2 + 1 ;
67
+ int rightIndex = root * 2 + 2 ;
68
+ boolean hasLeftChild = leftIndex < heap .length ;
69
+ boolean hasRightChild = rightIndex < heap .length ;
70
+ if (hasRightChild ) {
71
+ //if has left and right
72
+ makeMinHeap (leftIndex );
73
+ makeMinHeap (rightIndex );
74
+ heapSubtree (root , heap .length - 1 );
75
+ } else if (hasLeftChild ) {
76
+ heapSubtree (root , heap .length - 1 );
77
+ }
78
+ }
79
+
80
+ /**
81
+ * Gets the root of heap
82
+ *
83
+ * @return root of heap
84
+ */
85
+ private T getRoot (int size ) {
86
+ swap (heap , 0 , size );
87
+ heapSubtree (0 , size - 1 );
88
+ // return old root
89
+ return heap [size ];
90
+ }
91
+
92
+
93
+ }
94
+
95
+ public <T extends Comparable <T >> T [] sort (T [] unsorted ) {
96
+ return sort (Arrays .asList (unsorted )).toArray (unsorted );
97
+ }
98
+
99
+ private <T extends Comparable <T >> List <T > sort (List <T > unsorted ) {
100
+ int size = unsorted .size ();
101
+
102
+ @ SuppressWarnings ("unchecked" )
103
+ Heap <T > heap = new Heap <>(unsorted .toArray ((T []) new Comparable [unsorted .size ()]));
104
+
105
+ // make min heap using index 0 as root.
106
+ heap .makeMinHeap (0 );
107
+ List <T > sorted = new ArrayList <>(size );
108
+ while (size > 0 ) {
109
+ T min = heap .getRoot (--size );
110
+ sorted .add (min );
111
+ }
112
+
113
+ return sorted ;
114
+ }
115
+ }
0 commit comments