標籤:演算法 堆排序
題目:
選擇排序法的概念簡單,每次從未排序部份選一最小值,插入已排序部份的後端,其時間主要花費於在整個未排序部份尋找最小值,如果能讓搜尋最小值的方式加 快,選擇排序法的速率也就可以加快
Heap排序法讓搜尋的路徑由樹根至最後一個樹葉,而不是整個未排序部份,從而可以加快排序的過程,因而稱之為改良的選擇排序法。
整個堆排序的過程分建堆、取值、調整為新的堆三個過程。分別如下示:(以最小堆積樹為例。關於HeapTree請參閱資料結構與演算法)
建堆 - 演算法
1、 加至堆積樹的元素會先放置在最後一個樹分葉節點位置
2、 然後檢查父節點是否小於子節點(最小堆積)
3、 將小的元素不斷與父節點交換,直到滿足堆積樹的條件為止
取最小值 – 演算法
1、將根節點與最後一葉子結點交換
2、樹長度減一,調整樹為新的堆積樹
調整為新堆積樹 – 演算法
1、 比較左孩子節點與右孩子節點,取其較小一個節點
2、 比較孩子節點與父節點,若父節點大則交換孩子與父節點,令孩子節點為新的父節點,並求其新的孩子節點;程式進入1.迴圈
SourceCodes
// 建立最小堆積樹- 建堆演算法// 1. 加至堆積元素先放置在最後一個葉子節點的位置// 2. 檢查父節點是否小於子節點,若小,則交換父節點與子節點// 3. 將父節點設定為新的子節點,同時求其新的父節點,程式進入.迴圈int CreatMinHeap3(int a[],int lens){int i;// 臨時增量變數int child,parent;// 子節點與父節點下標int* pheap=new int[lens];// 新的堆for(i=1;i<lens;i++){pheap[i]=a[i];child=i;parent=child/2;while(child>=2 && pheap[parent]>pheap[child]){SWAPER(pheap[parent],pheap[child]);child=parent;parent=child/2;}}for(i=1;i<lens;i++){a[i]=pheap[i];}delete pheap; pheap=NULL;return 0;}
// 調整最小堆積樹// 1. 比較左孩子節點與右孩子節點,取其較小一個節點// 2. 比較孩子節點與父節點,若父節點大則交換孩子與父節點,令孩子節點為新的父節點,並求其新的孩子節點,程式進入1.迴圈int AdjustMinHeap2(int a[],int specificlens){if(specificlens<2) return -1;if(specificlens==2) {if(a[1]>a[2]) SWAPER(a[1],a[2]);return 0;}int tail=specificlens;int parent=1;int child=2*parent;while(child+1<=tail){if(a[child]<a[child+1]){if(a[parent]>a[child]){SWAPER(a[parent],a[child]);parent=child;child=2*parent;}else break;}else{if(a[parent]>a[child+1]){SWAPER(a[parent],a[child+1]);parent=child+1;child=2*parent;}else break;}}return 0;}
// 堆排序// 1. 建立最小堆積樹// 2. 取下最小節點 (交換最小堆積樹的根與最後一個節點)// 3. 樹長度減一,調整新的堆為最小堆積樹.// 4. 程式進入.2迴圈int HeapSort(int a[],int lens){CreatMinHeap3(a,lens);int i = 0;int parent,child;int m=lens-1;while(m>1){SWAPER(a[1],a[m]);m--;AdjustMinHeap2(a,m);}return 0;}