堆排序
二叉堆是一个数组,可以将其看成是一个近似的完全二叉树
最大堆 父节点>=子节点 根节点最大
最小堆 父节点<=子节点 根节点最小
下标:
*Parent(i)
return i/2;
Left(i)
return 2*i;
Right(i)
return 2*i+1;
*
等比数列求和公式:(a1(1-q^n))/((1-q))
注:高度为h的二叉堆 元素最多:2^(h+1)-1最少:2^h
过程:元素最多:20+21+22+…+2h=2^(h+1)-1
元素最少:20+21+22+…+2h-1+1=2^h
另:含有n各元素的堆的高度为lgn,向下取整
过程: 2^h <=n<=2^(h+1)-1<2^(h+1)h<=lgn
MAX-HEAPIFY(A,i)
l=Left(i)
r=right(i)
if l<=size and A[l]>A[i]
largest=l
else
largest=i
if r<=size and A[r]>A[largest]
largest=r
if largest 不等于 i
exchange A[i] with A[largest]
MAX-HEAPIFY(A, largest)
构造最大堆算法
BUILD-MAX-HEAP(A)
heap.size = A.length
for i = A.length/2 downto 1
MAX-HEAPIFY(A,i)
堆排序算法
HEAPSORT(A)
BUILD-MAX-HEAP(A)
for i=A.length downto 2
exchange A[1] with A[i]
heap.size = A.heap.size-1
MAX-HEAPIFY(A,1)
java代码
import java.util.Random;
/**
*
* 利用最大堆进行排序
*
*/
public class Main {
private static int N = 10;// 数组的大小
static Random rand = new Random();
public static void main(String[] args) {
// TODO Auto-generated method stub
test_HeapSort();
}
private static void test_HeapSort() {
// TODO Auto-generated method stub
int[] A = new int[N+1];
A[0]=-1;
for (int i = 1; i <= N; i++) {
A[i] = rand.nextInt(1000);
}
System.out.println("排序前:");
print(A);
HeapSort(A);
System.out.println("排序后(升序):");
print(A);
}
/**
* 堆排序
* @param A
*/
private static void HeapSort(int[] A) {
// TODO Auto-generated method stub
Build_Max_Heap(A);
int length=A.length-1;
//每次将根节点与需要排序的最后一个数交换 后维持最大堆
for(int i=length; i>1;i--){
int temp = A[i];
A[i]=A[1];
A[1]=temp;
Max_Heapfy(A,1,--length);
}
}
/**
* 构建最大堆
* @param A
*/
private static void Build_Max_Heap(int[] A) {
// TODO Auto-generated method stub
int length=A.length-1;
for(int i=length/2;i>0;i--){
Max_Heapfy(A, i, length);
}
}
/**
* 维持最大堆
* @param A
* @param i 从第i个元素开始维护
* @param length 维持堆的数组长度
*/
private static void Max_Heapfy(int[] A,int i,int length) {
// TODO Auto-generated method stub
int l=left(i);
int r=right(i);
int largest=0;
if(l<=length && A[l]>A[i]){
largest=l;
}else{
largest=i;
}
if(r<=length && A[r]>A[largest]){
largest=r;
}
if(largest!=i){
int temp = A[i];
A[i]=A[largest];
A[largest]=temp;
Max_Heapfy(A,largest,length);
}
}
//父节点
private static int parent(int i) {
return i/2;
}
//左节点
private static int left(int i) {
return 2*i;
}
//右节点
private static int right(int i) {
return 2*i+1;
}
// 打印数组
private static void print(int[] A) {
// TODO Auto-generated method stub
for (int i = 1; i < A.length; i++) {
System.out.print(A[i] + "\t");
}
System.out.println();
}
}
运行截图: