1. 程式人生 > >堆排序 Java實現

堆排序 Java實現

    堆排序是利用這種資料結構而設計的一種排序演算法,堆排序是一種選擇排序,它的最壞,最好,平均時間複雜度均為O(nlogn),它也是不穩定排序。

堆是具有以下性質的完全二叉樹:每個結點的值都大於或等於其左右孩子結點的值,稱為大頂堆;或者每個結點的值都小於或等於其左右孩子結點的值。

堆排序的基本思路:

  a.將無需序列構建成一個堆,根據升序降序需求選擇大頂堆或小頂堆;

  b.將堆頂元素與末尾元素交換,將最大元素"沉"到陣列末端;

  c.重新調整結構,使其滿足堆定義,然後繼續交換堆頂元素與當前末尾元素,反覆執行調整+交換步驟,直到整個序列有序。

升序排序,則構建大頂堆。

package nuc.edu.lisheng;

import java.util.Arrays;

public class HeapSort {
	public static void main(String[] args) {
		int[] a = { 58, 4, 5, 9, 36, 27, 1, 3, 58 };
		HeapSortFianl(a);
		System.out.println(Arrays.toString(a));
	}
    //是否排序完成
	public static boolean ifend(int[] a) {
		// true代表還要繼續,即沒有排序好
		boolean ifend = true;
		A: for (int index = a.length - 1; index > 0; index--) {
			if (a[index] < a[index - 1]) {
				ifend = false;
				break A;
			}
		}
		return ifend;
	}
    //判斷a是否為奇數。(從0開始)完全二叉樹中奇數索引在左,偶數索引在右。左右對應的交換操作斌不相同
	public static boolean odd(int a) {
		if (a % 2 == 0) {
			return false;
		} else {
			return true;
		}
	}
    //左右節點與父節點比較大小,交換
	public static void sortHeap(int[] a, int i, int changeIndex) {
		//如果是偶數
		if (!odd(i)) {
			int left = i - 1;
			int father = (i - 1) / 2;
			if (a[i] > a[father]) {
				int num = a[i];
				a[i] = a[father];
				a[father] = num;
			}
			if (a[left] > a[father]) {
				int num = a[left];
				a[left] = a[father];
				a[father] = num;
			}
		} else {
			//如果是奇數,且在可操作的最後一位,那麼沒有右節點,直接比較左節點即可
			if (i == changeIndex) {
				int father = i / 2;
				if (a[i] > a[father]) {
					int num = a[i];
					a[i] = a[father];
					a[father] = num;
				}
			} else {
				//左右都有,都比較
				int right = i + 1;
				int father = i / 2;
				if (a[i] > a[father]) {
					int num = a[i];
					a[i] = a[father];
					a[father] = num;
				}
				if (a[right] > a[father]) {

					int num = a[right];
					a[right] = a[father];
					a[father] = num;

				}
			}

		}
	}

	public static void getMaxHeap(int[] a, int changeIndex) {
		//從可操作的最後一位往後比較,直到1為止。
		for (int i = changeIndex; i > 0; i--) {
			sortHeap(a, i, changeIndex);
		}
	}
    //可操作的最後一位與守衛交換
	public static void changeFirstAndEnd(int[] a, int changeIndex) {
		int num = a[changeIndex];
		a[changeIndex] = a[0];
		a[0] = num;

	}

	public static void HeapSortFianl(int[] a) {
		int changeIndex = a.length - 1;
		A: while (true) {
			getMaxHeap(a, changeIndex);
			changeFirstAndEnd(a, changeIndex);
			changeIndex--;
			if (ifend(a)) {
				break A;
			}
		}

	}
}

結果: