Java 堆排序(大根堆及小根堆)
阿新 • • 發佈:2019-01-25
整理網上的最大堆及最小堆程式碼
public abstract class Sorter {
public abstract void sort(int[] array);
}
public class HeapSorter extends Sorter {
@Override
public void sort(int[] array) {
heapSort(array);
}
/**
* 堆排序方法
* 基於大根堆實現
* @param array
*/
private void heapSort(int[] array) {
Integer tmp;//暫存交換元素
buildHeap(array);//執行初始建堆,並調整
for (int i=0;i<array.length;i++){
// 交換堆頂元素array[0]和堆中最後一個元素array[array.length-1-i]
tmp=array[0];
array[0]=array[array.length-i-1];
array[array.length-i-1]=tmp;
// 每次交換堆頂元素和堆中最後一個元素之後,都要對堆進行調整
adjustHeap(array,0,array.length-i-1);
}
}
/**
* <p>
* 調整堆的方法
* @param i 待調整結點的索引
* @param m 待調整堆的結點的數量(即:排除葉子結點)
*/
private void adjustHeap(int[] array, int i, int m) {
Integer tmp = array[i]; // 當前待調整的結點
int s = 2 * i + 1; // 當前待調整結點的左孩子結點的索引(s+1為當前調整結點的右孩子結點的索引)
while (s < m) {
if (s + 1 < m && array[s] < array[s + 1]) { // 如果右孩子大於左孩子(找到比當前待調整結點大的孩子結點)
s=s+1;
}
if (array[i]<array[s]){
array[i]=array[s];// 孩子結點大於當前待調整結點,將孩子結點放到當前待調整結點的位置上
i=s;// 重新設定待調整的下一個結點的索引
s=2*i+1;
}else{// 如果當前待調整結點大於它的左右孩子,則不需要調整,直接退出
break;
}
array[i]=tmp;// 當前待調整的結點放到比其大的孩子結點位置上
}
}
/**
* 建堆方法
* 並調整0-array.length/2個節點,保持堆的性質
* @param array
*/
private void buildHeap(int[] array) {
// 求出當前堆中最後一個存在孩子結點的索引
int pos=(array.length-1)/2;
// 從該結點結點開始,執行建堆操作
for (int i=pos;i>=0;i--){
adjustHeap(array,i,array.length);// 在建堆過程中,及時調整堆中索引為i的結點
}
}
/**
* 最小堆
* @param a
* @param n
*/
//構建最小堆
public static void MakeMinHeap(int a[], int n){
for(int i=(n-1)/2 ; i>=0 ; i--){
MinHeapFixdown(a,i,n);
}
}
//從i節點開始調整,n為節點總數 從0開始計算 i節點的子節點為 2*i+1, 2*i+2
public static void MinHeapFixdown(int a[],int i,int n){
int j = 2*i+1; //子節點
int temp = 0;
while(j<n){
//在左右子節點中尋找最小的
if(j+1<n && a[j+1]<a[j]){
j++;
}
if(a[i] <= a[j])
break;
//較大節點下移
temp = a[i];
a[i] = a[j];
a[j] = temp;
i = j;
j = 2*i+1;
}
}
public static void MinHeap_Sort(int a[],int n){
int temp = 0;
MakeMinHeap(a,n);
for(int i=n-1;i>0;i--){
temp = a[0];
a[0] = a[i];
a[i] = temp;
MinHeapFixdown(a,0,i);
}
}
public static void main(String[] args) {
int array[]={1,6,9,45,65,12,3,4,578,78,5,6,13,458,12,456,789,123};
HeapSorter heapSorter=new HeapSorter();
heapSorter.heapSort(array);
// heapSorter.MinHeap_Sort(array,array.length);
for (int i:array){
System.out.print(i+" ");
}
System.out.println(" ");
}
}