堆数据结构是一种数组对象,它可以被视为一颗完全二叉树。堆的访问可以通过三个函数来进行即,
parent(i)
return floor(i/2);
left(i)
return 2i;
right(i)
return 2i + 1;left操作可以通过一步左移操作完成,right操作可以通过左移并在地位+1实现,parent操作则可以通过把i右移一位得到。在实现中通常会使用宏或者内联函数来实现这三个操作。
二叉堆有两种,最大堆和最小堆。对于最大堆有
A[i] >= A[left(i)] && A[i] >= A[right(i)]
最小堆则是
A[i] <= A[left(i)] && A[i]<= A[right(i)]
最堆排序算法中,使用的是最大堆,最小堆通常在构造优先队列时使用。堆可以被看成是一棵树,结点在堆中的高度定义为从本结点到叶子的最长简单下降路径上边的数目;定义堆的高度为树根的高度。
下面就关于堆的几个基本函数做一下说明:
maxHeapify(),运行时间为O(lgn)用于保持堆的性质;
bulidMaxHeap(),以线性时间运行,可以在无序的输入数组基础上构造出最大堆;
heapSort(),运行时间为O(nlgn),对一个数组原地进行排序。
maxHeapify(A,i)
l <- left(i)
r <- right(i)
if l <= heap-size[A] and A[l] > A[i]
then largest <- l
else largest <- i
if r <= heap-size[A] and A[r] > A[largest]
then largest <- r
if largest != i
then exchange A[i] <-> A[largest] // 交换i和比它大的那个子结点
maxHeapify(A,largest); // 递归调用
buildMaxHeap(A)
heap-size[A] <- length[A]
for i <- floor(length[A] / 2) downto 1
do max-heapify(A,i)
heapSort(A)
buildMaxHeap(A)
for i <- length[A] downto 2
do exchange A[1] <-> A[i]
heap-size[A] <- heap-size[A] - 1
maxHeapify(A,1)import java.io.Serializable;
/**
* Date: 2014/8/17
* Time: 16:02
*/
public class Heap implements Serializable{
private int heapLength;
private int [] data;
public int getHeapLength() {
return heapLength;
}
public void setHeapLength(int heapLength) {
this.heapLength = heapLength;
}
public int[] getData() {
return data;
}
public void setData(int[] data) {
this.data = data;
}
}
/**
* Created with IntelliJ IDEA.
* Date: 2014/8/17
* Time: 15:39
*/
public class HeapSort {
public final static int getLeft(int i) {
return i << 1;
}
public final static int getRight(int i) {
return (i << 1) + 1;
}
public final static int getParent(int i) {
return i >> 1;
}
/**
* 保持堆的性质
*
* @param heap
* @param i
*/
public static void maxHeapify(Heap heap, int i) {
if (null == heap || null == heap.getData() || heap.getData().length <= 0 || i < 0)
return;
int l = getLeft(i);
int r = getRight(i);
int largest = 0;
if (l < heap.getHeapLength() && heap.getData()[l] > heap.getData()[i])
largest = l;
else
largest = i;
if (r < heap.getHeapLength() && heap.getData()[r] > heap.getData()[largest])
largest = r;
if (largest != i) {
int tmp = heap.getData()[i];
heap.getData()[i] = heap.getData()[largest];
heap.getData()[largest] = tmp;
maxHeapify(heap, largest);
}
}
/**
* 建立最大堆
*
* @param array
* @return
*/
public static Heap bulidMaxHeap(int[] array) {
if (null == array || array.length <= 0)
return null;
Heap heap = new Heap();
heap.setData(array);
heap.setHeapLength(array.length);
for (int i = (array.length >> 1); i >= 0; i--)
maxHeapify(heap, i);
return heap;
}
/**
* 堆排序
*
* @param array
*/
public static void heapSort(int[] array) {
if (null == array || array.length <= 0)
return;
Heap heap = bulidMaxHeap(array);
if (null == heap)
return;
for (int i = heap.getHeapLength() - 1; i > 0; i--) {
int tmp = heap.getData()[0];
heap.getData()[0] = heap.getData()[i];
heap.getData()[i] = tmp;
heap.setHeapLength(heap.getHeapLength() - 1);
maxHeapify(heap, 0);
}
}
}
public class Main {
public static void main(String[] args) {
int a[] = {9, 3, 4, 1, 5, 10, 7};
System.out.println("Hello World!");
Sort sort = new Sort();
// sort.bubbleSort(a);
// sort.selectSort(a);
// sort.insertionSort(a);
HeapSort.heapSort(a);
for (int i = 0; i < a.length; i++)
System.out.println(a[i]);
}
}
原文:http://blog.csdn.net/bob_dadoudou/article/details/38638623