Comparator接口
package MyInterface;
public interface Comparator<T> {
int compare(T x, T y);
}
package Heap;
import MyInterface.Comparator;
public class Greater<T> implements Comparator<T> {
public int compare(T x, T y) {
return -((Comparable<T>)x).compareTo(y);
}
}
package Heap;
import MyInterface.Comparator;
public class Less<T> implements Comparator<T> {
public int compare(T x, T y) {
return ((Comparable<T>)x).compareTo(y);
}
}
package Heap;
import MyInterface.Comparator;
public class Heaps {
/**
* 建堆
*/
public static <T> void pushHeap(T[] arr, int last, T item,
Comparator<? super T> comp) {
int currPos, parentPos;
currPos = last;
parentPos = (currPos - 1) / 2;
while (currPos != 0) {
if (comp.compare(item, arr[parentPos]) < 0) {
arr[currPos] = arr[parentPos];
currPos = parentPos;
parentPos = (currPos - 1) / 2;
} else
break;
}
arr[currPos] = item;
}
/**
* 删除操作
*/
public static <T> T popHeap(T[] arr, int last, Comparator<? super T> comp) {
T tmp = arr[0];
arr[0] = arr[last - 1];
arr[last - 1] = tmp;
adjustHeap(arr, 0, last - 1, comp);
return tmp;
}
/**
* 调整堆
*/
private static<T> void adjustHeap(T[] arr, int first, int last,
Comparator<? super T> comp) {
int currPos, childPos;
T target;
currPos = first;
target = arr[first];
childPos = 2 * currPos + 1;
while(childPos < last) {
//首先比较左右孩子大小,取大值
if((childPos + 1 < last) &&
comp.compare(arr[childPos + 1], arr[childPos]) < 0)
childPos = childPos + 1;
//再比较目标值
if(comp.compare(arr[childPos], target) < 0) {
arr[currPos] = arr[childPos];
currPos = childPos;
childPos = 2 * currPos + 1;
}else
break;
}
arr[currPos] = target;
}
/**
* 堆的产生
* 从位于索引(n-2)/2处的最后一个父结点开始,到位于索引0处的根结点结束,向上
* 过滤树中的每个父结点,就可以将n元素数组转换成堆.
*/
public static <T> void makeHeap(T[] arr, Comparator<? super T> comp) {
int heapPos, lastPos;
lastPos = arr.length;
heapPos = (lastPos - 2) / 2;
//heapPos = ((lastPos - 1) - 1) / 2;
while(heapPos >= 0) {
adjustHeap(arr, heapPos, lastPos, comp);
heapPos--;
}
}
/**
* 堆排序
* 最大堆以升序对数组进行排序,最小堆以降序.
*/
public static <T> void heapSort(T[] arr, Comparator<? super T> comp) {
Heaps.makeHeap(arr, comp);
int len = arr.length;
for(int i = len; i > 1; i--) {
Heaps.popHeap(arr, i, comp);
}
}
}
package Heap;
import MyInterface.Comparator;
public class TestHeap {
public static void main(String[] args) {
Integer[] arr = {15, 29, 52, 17, 21, 39, 8},
arrA = new Integer[arr.length],
arrB = new Integer[arr.length];
Greater<Integer> greater = new Greater<Integer>();
Less<Integer> less = new Less<Integer>();
for(int i = 0; i < arr.length; i++) {
Heaps.pushHeap(arrA, i, arr[i], greater);
Heaps.pushHeap(arrB, i, arr[i], less);
}
//打印最大堆
for(int i = 0; i < arrA.length; i++)
System.out.print(arrA[i] + " "); // 52 21 39 15 17 29 8
System.out.println();
//打印最小堆
for(int i = 0; i < arrB.length; i++)
System.out.print(arrB[i] + " "); // 8 17 15 29 21 52 39
Integer maxValue = Heaps.popHeap(arrA, arrA.length, greater);
Integer minValue = Heaps.popHeap(arrB, arrB.length, less);
System.out.println('\n' + "max value is: " + maxValue); // max value is: 52
System.out.println("min value is: " + minValue); // min value is: 8
// 测试堆排序
Heaps.heapSort(arrA, greater);
Heaps.heapSort(arrB, less);
for (int i = 0; i < arrA.length; i++) {
System.out.print(arrA[i] + " "); // 8 15 17 21 29 39 52
}
System.out.println();
for (int i = 0; i < arrB.length; i++) {
System.out.print(arrB[i] + " "); // 52 39 29 21 17 15 8
}
}
}