一.堆的定义
堆是计算机科学中一类特殊的数据结构的统称,堆通常可以被看做是一棵完全二叉树的数组对象。
二.API设计
三.代码实现
public class Heap<T extends Comparable<T>>{
private T[] items;
private int length;
public Heap(int capacity) {
this.length = 0;
items = (T[])new Comparable[capacity + 1];
}
/**
* 比较两个节点的大小
* @param i
* @param j
* @return
*/
private boolean less(int i,int j){
return items[i].compareTo(items[j]) < 0;
}
private void swap(int i,int j){
T temp = items[i];
items[i] = items[j];
items[j] = temp;
}
public void insert(T t){
items[++length] = t;
swim(length);
}
// 上浮算法
private void swim(int k){
while( k > 1){
if (less(k/2,k)) swap(k,k/2);
k /= 2;
}
}
public T deleteMax(){
T max = items[1];
swap(1,length);
items[length] = null;
length--;
sink(1);
return max;
}
private void sink(int k){
while(k*2 <= length){
int max;
if(k*2+1 <= length){
if (less(k*2,k*2+1)) max = k*2+1;
else max = k*2;
}else{
max = k*2;
}
if (less(k,max)) swap(k,max);
else return;
}
}
}
四.堆排序
import java.util.Arrays;
import java.util.Random;
public class HeapSort {
/**
* 对source数组中的数据从小到大排列
*
* @param source
*/
public static void sort(Comparable[] source) {
Comparable[] heap = new Comparable[source.length + 1];
createHeap(source, heap);
int N = heap.length - 1;
while (N != 1) {
wrap(heap, 1, N);
N--;
sink(heap, 1, N);
}
System.arraycopy(heap, 1, source, 0, source.length);
}
private static void createHeap(Comparable[] source, Comparable[] heap) {
System.arraycopy(source, 0, heap, 1, source.length);
// 对堆中元素做下沉处理
for (int i = (heap.length - 1) / 2; i > 0; i--) {
sink(heap, i, heap.length - 1);
}
}
/**
* 判断heap堆中索引i处的元素是否小于索引j处的元素
*
* @param heap
* @param i
* @param j
* @return
*/
private static boolean less(Comparable[] heap, int i, int j) {
return heap[i].compareTo(heap[j]) < 0;
}
/**
* 交换heap堆中i索引和j索引处的值
*
* @param heap
* @param i
* @param j
*/
private static void wrap(Comparable[] heap, int i, int j) {
Comparable temp = heap[i];
heap[i] = heap[j];
heap[j] = temp;
}
/**
* 在heap堆中,对target处元素做下沉,范围是0~range
*
* @param heap
* @param target
* @param range
*/
private static void sink(Comparable[] heap, int target, int range) {
while (2 * target <= range) {
int max;
if (2 * target + 1 <= range) {
if (less(heap, 2 * target, 2 * target + 1)) max = 2 * target + 1;
else max = 2 * target;
} else {
max = 2 * target;
}
if (less(heap, target, max)) wrap(heap, max, target);
target = max;
}
}
public static Integer[] randomArray(int N) {
Random random = new Random();
Integer[] array = new Integer[N];
for(int i = 0;i < N;i++){
array[i] = random.nextInt(100);
}
return array;
}
public static void main(String[] args) {
Integer[] array = randomArray(10);
sort(array);
System.out.println(Arrays.toString(array));
}
}