科班出身的程式設計師就應該研究些演算法和資料結構類的東西,不然,有什麼優勢?
堆排序,結構是完全二叉樹,選擇排序的一種,其流程控制和氣泡排序類似,每次選出乙個最大(或最小的元素)排出去,然後下一輪再選出乙個最大(最小的),以此類推,直到剩下乙個不能構成二叉樹為止也排出去,排出來的就是有序的了。只不過每次選極值元素不是對所有元素都對比,而是心中模擬有一棵完全二叉樹,每次選出最大頂(最小頂)。
原理解析:
給定乙個列表array=[16,7,3,20,17,8],對其進行堆排序。
首先根據該陣列元素構建乙個完全二叉樹,得到
然後需要構造初始堆,則從最後乙個非葉節點開始調整,調整過程如下:
第一步: 初始化大頂堆(從最後乙個有子節點開始往上調整最大堆)
20和16交換後導致16不滿足堆的性質,因此需重新調整
這樣就得到了初始堆。
第二步: 堆頂元素r[1]與最後乙個元素r[n]交換,交換後堆長度減一
即每次調整都是從父節點、左孩子節點、右孩子節點三者中選擇最大者跟父節點進行交換(交換之後可能造成被交換的孩子節點不滿足堆的性質,因此每次交換之後要重新對被交換的孩子節點進行調整)。有了初始堆之後就可以進行排序了。
第三步: 重新調整堆。此時3位於堆頂不滿堆的性質,則需調整繼續調整(從頂點開始往下調整)
重複上面的步驟:
注意了,現在你應該了解堆排序的思想了,給你一串列表,你也能寫出&說出堆排序的過程。
在寫演算法的過程中,剛開始我是很懵比。後來終於看懂了。請特別特別注意: 初始化大頂堆時 是從最後乙個有子節點開始往上調整最大堆。而堆頂元素(最大數)與堆最後乙個數交換後,需再次調整成大頂堆,此時是從上往下調整的。
不管是初始大頂堆的從下往上調整,還是堆頂堆尾元素交換,每次調整都是從父節點、左孩子節點、右孩子節點三者中選擇最大者跟父節點進行交換,交換之後都可能造成被交換的孩子節點不滿足堆的性質,因此每次交換之後要重新對被交換的孩子節點進行調整。我在演算法中是用乙個while迴圈來解決的
參考**:
1 public class heapsort 10 // 如果父結點的值已經大於孩子結點的值,則直接結束 11 if (temp >= array[child]) 12 break; 13 // 把孩子結點的值賦給父結點 14 array[parent] = array[child]; 15 // 選取孩子結點的左孩子結點,繼續向下篩選 16 parent = child; 17 child = 2 * child + 1; 18 } 19 array[parent] = temp; 20 } 21 public void heapsort(int list) 26 // 進行n-1次迴圈,完成排序 27 for (int i = list.length - 1; i > 0; i--) 37 } 38 // 列印序列 39 public void printpart(int list, int begin, int end) 43 for (int i = begin; i <= end; i++) 46 system.out.println(); 47 } 48 public static void main(string args) ; 51 // 呼叫堆排序方法 52 heapsort heap = new heapsort(); 53 system.out.print("排序前:t"); 54 heap.printpart(array, 0, array.length - 1); 55 heap.heapsort(array); 56 system.out.print("排序後:t"); 57 heap.printpart(array, 0, array.length - 1); 58 } 59 }
時間複雜度:
堆的儲存表示是順序的。因為堆所對應的二叉樹為完全二叉樹,而完全二叉樹通常採用順序儲存方式。
當想得到乙個序列中第k個最小的元素之前的部分排序序列,最好採用堆排序。
因為堆排序的時間複雜度是o(n+klog2n),若k≤n/log2n,則可得到的時間複雜度為o(n)。
演算法穩定性:
堆排序是一種不穩定的排序方法。
因為在堆的調整過程中,關鍵字進行比較和交換所走的是該結點到葉子結點的一條路徑,
因此對於相同的關鍵字就可能出現排在後面的關鍵字被交換到前面來的情況。
最後看一下排序家族
堆排序時間複雜度 堆排序演算法
堆排序是指利用堆積樹這種資料結構所設計的一種排序演算法,它是選擇排序的一種。可以利用陣列的特點快速定位指定索引的元素。堆是乙個優先順序佇列,對於大頂堆而言,堆頂元素的權值最大。將待排序的數組建堆,然後不斷地刪除堆頂元素,就實現了排序。堆排序基本思想 將待排序序列構造成乙個大頂堆,此時,整個序列的最大...
堆排序時間複雜度的理解
堆排序 這裡不再贅述堆的定義 和堆排序的講解,詳見海子的部落格 裡面圖示已經很清楚了,這裡首先對該部落格對我的啟發表示感謝。難點 1.對堆的理解 從堆的定義可以看出,堆有兩個性質 i.完全二叉樹 即按二叉樹逐層從左到右排列資料,這樣便於所以某個節點的父節點或者子節點 ii.大頂堆 或小頂堆 即任何父...
堆排序時間複雜度 基於PHP實現堆排序原理
每日17點準時技術乾貨分享 堆 堆 heap 是電腦科學中一類特殊的資料結構的統稱,通常是乙個可以被看做一棵樹的陣列物件。堆 ki k2i,ki k2i 1 ki k2i,ki k2i 1 i 1,2,3,4.n 2 關於堆 完全二叉樹 說到堆排序,就不能不提完全二叉樹,這些基本概念在網上到處都是,...