package com.mylearn;
import java.util.*;
/**
* 本程序是進行堆排序 首先需要明白堆是一種特殊的完全二叉樹,並且它的孩子結點永遠小於父母結點 —— 基本思想:
* 堆排序是一種樹形選擇排序,是對直接排序算法的有效改進。堆的定義如下:具有n個元素的序列(h1,h2,…,hn),當且僅當滿足(hi>=h2i,hi>=2i
* +1)或(hi<=h2i,hi<=2i+1)
* (i=1,2,…,n/2)時稱之爲堆。在這裏只討論滿足前者條件的堆。由堆的定義可以看出,堆頂元素(即第一個元素)必爲最大項(大頂堆)。
* 完全二叉樹可以很直觀地表示堆的結構。堆頂爲根,其它爲左子樹、右子樹。初始時把要排序的數的序列看作是一棵順序存儲的二叉樹,調整它們的存儲序,使之成爲一個堆,
* 這時堆的根節點的數最大。然後將根節點與堆的最後一個節點交換。然後對前面(n-1)個數重新調整使之成爲堆。依此類推,直到只有兩個節點的堆,並對它們作交換,
* 最後得到有n個節點的有序序列。從算法描述來看,堆排序需要兩個過程,一是建立堆,二是堆頂與堆的最後一個元素交換位置。所以堆排序有兩個函數組成。
* 一是建堆的滲透函數,二是反覆調用滲透函數實現排序的函數。
*
* @author H
*
*/
public class DuiPaiXu {
public static void main(String[] args) {
// 聲明一個列表,存儲數據
Integer[] list = { 1, 0, -2, 3, 5, 1, 2, 10, 11, 21, 3, 2 };
heapsort(list);
for (Integer element : list)
System.out.println(element);
}
/*
* 首先編寫堆類 堆類用線性列表來存儲數據
*
*/
private ArrayList list = new ArrayList();
public DuiPaiXu(E[] objects) {
for (int i = 0; i < objects.length; i++)
add(objects[i]);
}
public DuiPaiXu() {
}
public void add(E object) {
list.add(object);
int currentindex = list.size() - 1;
while (currentindex > 0) {
int parentindex = (currentindex - 1) / 2;
/*
* 如果父類結點小於子類結點,則將它們交換值 這個過程一直持續到父類結點不再小於子類結點爲止
*/
if (list.get(parentindex).compareTo(list.get(currentindex)) < 0) {
E temp = list.get(currentindex);
list.set(currentindex, list.get(parentindex));
list.set(parentindex, temp);
} else
break;
currentindex = parentindex;// 把新加的數的下標更新
}
}
@SuppressWarnings("unchecked")
public E remove() {
if (list.size() == 0)
return null;
/*
* 基本思想是 remove()方法只能移除根處的元素 然後重新組建堆 首先把最後一個元素移到根處
* 然後將根與它的結點進行比較,若小於其子結點,則交換下移即可 直到下標最大爲止
*/
E removedObject = list.get(0);
list.set(0, list.get(list.size() - 1));
list.remove(list.size() - 1);
int currentindex = 0;
while (currentindex < list.size()) {
int leftchildindex = 2 * currentindex + 1;// 左孩子
int rightchildindex = 2 * currentindex + 2;// 右孩子
if (leftchildindex >= list.size())
break;
/*
* 下面語句確定左邊子結點與右邊子結點的大小 以便將父結點與最大的子結點進行比較 進而確定是否執行交換動作
*/
int maxindex = leftchildindex;
if (rightchildindex < list.size()) {
if (list.get(maxindex).compareTo(list.get(rightchildindex)) < 0)
maxindex = rightchildindex;
}
/*
* 下面開始執行交換動作 若父結點比最大的子結點要小 則交換它們
*/
if (list.get(currentindex).compareTo(list.get(maxindex)) < 0) {
E temp = list.get(currentindex);
list.set(currentindex, list.get(maxindex));
list.set(maxindex, temp);
currentindex = maxindex;
}
/*
* 直到父結點不再小於最大的子結點爲止
*/
else
break;
}
return removedObject;
}
public static void heapsort(E[] list) {
DuiPaiXu heap = new DuiPaiXu();
for (int i = 0; i < list.length; i++)
heap.add(list[i]);
for (int i = list.length - 1; i >= 0; i--)
list[i] = heap.remove();
}
}
java之堆排序
java之堆排序
直接上代碼:
--------------------------------------------------------
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.