排序演算法之堆排序
阿新 • • 發佈:2018-12-18
堆排序
【1】堆排序的思想
堆排序的思想是指利用堆資料結構所設計的一種資料排序演算法。
堆:堆是一種特殊的完全二叉樹,最大堆的特點是它的結點的值總是不小於它的父節點的值(也就是說其父節點的值總是大於它的子節點的值),總是一顆完全二叉樹結構。
【2】堆排序過程
A:有輸入的無序陣列構成一個完全二叉樹結構
B:先由此完全二叉樹構成一個最大堆,作為初始堆(一直交換查詢找到最大值放到根節點)
C:將堆頂元素和堆尾的元素交換(此時已經找出了最大值)
D:將堆尾元素從堆中撇開,剩下的的堆尺寸減一,此時的新堆繼續構成一個最大堆
E:一直重複BCD,直到堆的元素只剩一個
【3】堆的資料結構是陣列
【4】堆排序的穩定性:不穩定,發生在在堆頂元素和其它元素進行交換的時候
【5】堆排序的時間複雜度:O(nlogn)
剛開始建堆的時間複雜度是O(n)
在建立新堆並向下進行堆調整的時候,時間複雜度是O(logn)
堆排序程式碼如下:
package Collection; import java.util.Arrays; public class HeapSort { public static void main(String[] args) { int[] arr={5,2,9,4,7,6,1,3,8}; int n=arr.length; heapsort(arr,n); //呼叫堆排序函式 System.out.println(Arrays.toString(arr)); } public static void heapsort(int[] arr, int n){ int heap_size=buildheap(arr,n);//建立一個最大堆 while(heap_size>1){ //當堆內元素個數>1的時候 //這步操作很可能把後面元素的穩定性打亂,因此堆排序是不穩定的排序演算法 Swap(arr,0,-- heap_size);//將堆頂的元素和堆的最後一個元素互換(此時交換後的最後一個元素就是這個堆裡的最大元素) heapify(arr,0,heap_size);//在出過最後一個元素(最大值)之外重新排序(遞迴呼叫) } } public static int buildheap(int[] arr, int n){ int heap_size=n; for(int i=heap_size/2-1;i>=0;i--) //從最後一個非葉子結點開始向下進行堆調整 heapify(arr,i,heap_size); return heap_size; } public static void heapify(int[] arr, int i, int size){ int left_child=2*i+1;//第i結點的左孩子結點 int right_child=2*i+2; int max=i; //接下來找出此節點,此節點的左孩子,此節點的右孩子這三者之間誰最大 if(left_child<size&&arr[left_child]>arr[max]) max=left_child; if(right_child<size&&arr[right_child]>arr[max]) max=right_child; if(max!=i) { Swap(arr,i,max);//將最大值和當前結點交換 heapify(arr,max,size);//遞迴:從當前結點向下調整 } } public static void Swap(int[] arr, int x, int y){ int temp=arr[x]; arr[x]=arr[y]; arr[y]=temp; } }