1. 構建一個最大堆。對於給定的包含有n個元素的數組A[n],構建一個最大堆(最大堆的特性是,某個節點的值最多和其父節點的值一樣大。這樣,堆中的最大元素存放在根節點中;並且,在以某一個節點爲根的子樹中,各節點的值都不大於該子樹根節點的值)。從最底下的子樹開始,調整這個堆結構,使其滿足最大堆的特性。當爲了滿足最大堆特性時,堆結構發生變化,此時遞歸調整對應的子樹。
2. 堆排序算法,每次取出該最大堆的根節點(因爲根節點是最大的),同時,取最末尾的葉子節點來作爲根節點,從此根節點開始調整堆,使其滿足最大堆的特性。
3. 重複上一步操作,直到堆的大小由n個元素降到2個。如圖所示http://upload.wikimedia.org/wikipedia/commons/4/4d/Heapsort-example.gif
<pre name="code" class="java">package com.tangbo;
import java.util.Random;
import java.util.Scanner;
public class HeapSort {
static Scanner scanner;
static Random random = new Random();
public static void main(String[] args) {
print(heapSort(buidMaxHeap(productArray())));//生成數組,建堆,堆排序,打印
}
static void print(int []array)//打印函數
{
for(int i=0;i<array.length;i++)
{
System.out.print(array[i]+" ");
}
System.out.println();
}
static int [] productArray()//生成一個數組
{
int arrayayLength=0;
System.out.println("請輸入數組長度:");
scanner = new Scanner(System.in);
arrayayLength = scanner.nextInt();
int [] arrayayTemp = new int[arrayayLength];
for (int i = 0; i < arrayayLength; i++) {
arrayayTemp[i]=random.nextInt(1000);
}
return arrayayTemp;
}
static int[] heapSort(int [] array)//堆排序
{
int tempValue=0;
int arrayLength = array.length;
for(int i=arrayLength-1;i>=0;i--)
{
tempValue = array[i];
array[i] = array[0];
array[0] = tempValue;
maxHeapify(array,0,i);
}
return array;
}
static int [] buidMaxHeap(int [] array)//健最大堆
{
int arrayLength = array.length;
for(int i=array.length/2-1;i>=0;i--)
{
maxHeapify(array, i,arrayLength);
}
return array;
}
static int [] maxHeapify(int [] array,int i,int heapSize)//堆維護
{
int leftIndex,rightIndex,largest,tempValue;
leftIndex = 2*i+1;
rightIndex = 2*i+2;
if(leftIndex<heapSize && array[leftIndex]>array[i])
{
largest = leftIndex;
}else
{
largest = i;
}
if(rightIndex<heapSize && array[rightIndex]>array[largest])
{
largest = rightIndex;
}
if(largest!=i)
{
tempValue = array[largest];//交換
array[largest] = array[i];
array[i] = tempValue;
maxHeapify(array, largest,heapSize);//維護下一個
}
return array;
}
}