排序演算法(5)堆排序
阿新 • • 發佈:2019-01-26
一:基本思想
堆排序是利用堆(一種近似完全二叉樹的結構)這種資料結構設計的一種排序演算法
(1)由輸入的無序陣列構造一個最大堆,作為初始的無序區
(2)把堆頂元素(最大值)和堆尾元素進行互換
(3)把堆的尺寸縮小1,並呼叫heapify(A,0)從新的堆頂元素開始進行堆調整
(4)重複步驟(2),直到堆的尺寸為1
二.概覽
分類:內部比較排序
資料結構:陣列
最差時間複雜度:O(nlogn)
最優時間複雜度:O(nlogn)
平均時間複雜度:O(nlogn)
所需輔助空間:O(1)
穩定性:不穩定(不穩定發生在棧頂元素與a[i]交換的時候)
比如序列:{ 9, 5, 7, 5 },堆頂元素是9,堆排序下一步將9和第二個5進行交換,得到序列 {
三.程式碼實現
public class Heap { //交換函式 public static void Swap(int A[], int i, int j) { int temp = A[i]; A[i] = A[j]; A[j] = temp; } //建堆 public static int BuildHeap(int a[]){ int heap_size = a.length; for (int i = heap_size/2-1;i >=0;i--){ heapify(a,i,heap_size ); } return heap_size; } //堆調整 public static void heapify(int a[],int i,int size){ int left_child = 2*i +1; //左孩子索引 int right_child = 2*i + 2; //右孩子索引 int max = i; if(left_child<size && a[left_child]>a[max]){ max = left_child; } if(right_child<size && a[right_child]>a[max]){ max = right_child; } if (max != i){ Swap(a, max, i); //把當前結點和它的最大子結點進行互換 heapify(a, max, size);//遞迴呼叫,繼續從當前結點向下調整(注意下是指根) } } //堆排序 public static void sort(int a[]){ //建立一個大堆 int heap_size = BuildHeap(a); while (heap_size > 1){ // 大於1表示未完成排序 //將堆頂元素與最後一個元素交換,並從堆中去掉最後一個元素 //此處的交換很可能把後面的元素的穩定性打亂,所以堆排序不是穩定的排序 Swap(a, 0, --heap_size); //從新的堆頂元素開始向下調整,時間複雜度o(logn) heapify(a, 0, heap_size); } } }