一、堆性質
n個關鍵字序列k1,k2,.........kn當且僅當滿足一下性質是爲一個堆
- k[i]<=k[2i]
- k[i]<=k[2i+1](1≤i≤ n/2)
1、堆的構建
注意,被調整的節點,還有子節點的情況,需要遞歸進行調整。
2、堆的插入
3、堆的刪除
二、堆排序
堆排序(Heapsort)是指利用堆積樹(堆)這種數據結構所設計的一種排序算法,它是選擇排序的一種。可以利用數組的特點快速定位指定索引的元素。堆分爲大根堆和小根堆,是完全二叉樹。大根堆的要求是每個節點的值都不大於其父節點的值,即A[PARENT[i]] >= A[i]。在數組的非降序排序中,需要使用的就是大根堆,因爲根據大根堆的要求可知,最大的值一定在堆頂。
package Sort;
/**
* Created by LemonTree on 2017/4/5.
*/
public class HeapSort {
/**
* 調整堆
* @param array 原始堆
* @param index 調整位置
* @param heapSize 堆大小
*/
public static void adjustHeap(int[] array,int index, int heapSize){
int left = 2*index+1;
int right = 2*index+2;
int largest = index;
if(left<heapSize && array[index]<array[left])
largest = left;
if(right<heapSize && array[largest]<array[right])
largest = right;
if(largest!=index) {
int temp = array[largest];
array[largest] = array[index];
array[index] = temp;
adjustHeap(array, largest, heapSize); //遞歸調整
}
}
/**
* 建立堆
* @param array 待建堆序列
*/
public static void buildHeap(int array[]){
for(int i=array.length/2-1;i>=0;i--){
adjustHeap(array,i,array.length); //如看成完全二叉樹,那麼則從樹的第一個非葉子節點進行調整,順序爲array.length/2-1 ------>0,從後向前
}
}
/**
* 堆排序
* @param array 堆排序
*/
public static void sort(int[] array){
buildHeap(array);
for(int i=array.length-1;i>=0;i--){
int temp = array[0];
array[0] = array[i];
array[i] = temp;
adjustHeap(array,0,i); //每次堆的大小遞減
}
}
public static void main(String[] args) {
int[] array={9,3,4,6,1,2,3,45,6};
sort(array);
for(int num:array){
System.out.print(String.valueOf(num)+" ");
}
}
}
三、應用
題目:從1億個數中求出最大的前100個數。
思路:建立一個100元素的小頂堆,每次從剩下的數裏面取插入,如果比堆頂小則不比較,如果比堆頂大則相比較調整堆。大頂堆雖然也可以,但是浪費了堆的性質,不能像小頂堆一樣減少比較的次數。