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