java之堆排序

java之堆排序

直接上代碼:
--------------------------------------------------------
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();

	}

}

------------------------------------------------------------------------------------------------------------------------------------

更多請關注:FlyTester,關注技術的測試

QQ羣:456850134

web站:www.flytester.org

微信掃描二維碼關注:


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章