1. 程式人生 > 實用技巧 >十大經典排序演算法(七、堆排序)

十大經典排序演算法(七、堆排序)

堆排序可以說是一種利用堆的概念來排序的選擇排序。分為兩種方法:

  1. 大頂堆:每個節點的值都大於或等於其子節點的值,在堆排序演算法中用於升序排列;
  2. 小頂堆:每個節點的值都小於或等於其子節點的值,在堆排序演算法中用於降序排列;

演算法步驟

  1. 建立一個堆 H[0……n-1];

  2. 把堆首(最大值)和堆尾互換;

  3. 把堆的尺寸縮小 1,並呼叫 shift_down(0),目的是把新的陣列頂端資料調整到相應位置;

  4. 重複步驟 2,直到堆的尺寸為 1。

JavaScript

 1 var len;    // 因為宣告的多個函式都需要資料長度,所以把len設定成為全域性變數
 2 
 3 function
buildMaxHeap(arr) { // 建立大頂堆 4 len = arr.length; 5 for (var i = Math.floor(len/2); i >= 0; i--) { 6 heapify(arr, i); 7 } 8 } 9 10 function heapify(arr, i) { // 堆調整 11 var left = 2 * i + 1, 12 right = 2 * i + 2, 13 largest = i; 14 15 if (left < len && arr[left] > arr[largest]) {
16 largest = left; 17 } 18 19 if (right < len && arr[right] > arr[largest]) { 20 largest = right; 21 } 22 23 if (largest != i) { 24 swap(arr, i, largest); 25 heapify(arr, largest); 26 } 27 } 28 29 function swap(arr, i, j) { 30 var
temp = arr[i]; 31 arr[i] = arr[j]; 32 arr[j] = temp; 33 } 34 35 function heapSort(arr) { 36 buildMaxHeap(arr); 37 38 for (var i = arr.length-1; i > 0; i--) { 39 swap(arr, 0, i); 40 len--; 41 heapify(arr, 0); 42 } 43 return arr; 44 }

Python

 1 def buildMaxHeap(arr):
 2     import math
 3     for i in range(math.floor(len(arr)/2),-1,-1):
 4         heapify(arr,i)
 5 
 6 def heapify(arr, i):
 7     left = 2*i+1
 8     right = 2*i+2
 9     largest = i
10     if left < arrLen and arr[left] > arr[largest]:
11         largest = left
12     if right < arrLen and arr[right] > arr[largest]:
13         largest = right
14 
15     if largest != i:
16         swap(arr, i, largest)
17         heapify(arr, largest)
18 
19 def swap(arr, i, j):
20     arr[i], arr[j] = arr[j], arr[i]
21 
22 def heapSort(arr):
23     global arrLen
24     arrLen = len(arr)
25     buildMaxHeap(arr)
26     for i in range(len(arr)-1,0,-1):
27         swap(arr,0,i)
28         arrLen -=1
29         heapify(arr, 0)
30     return arr

C語言

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 void swap(int *a, int *b) {
 5     int temp = *b;
 6     *b = *a;
 7     *a = temp;
 8 }
 9 
10 void max_heapify(int arr[], int start, int end) {
11     // 建立父節點指標和子節點指標
12     int dad = start;
13     int son = dad * 2 + 1;
14     while (son <= end) { // 若子節點指標在範圍內才做比較
15         if (son + 1 <= end && arr[son] < arr[son + 1]) // 先比較兩個子節點大小,選擇最大的
16             son++;
17         if (arr[dad] > arr[son]) //如果父節點大於子節點代表調整完畢,直接跳出函式
18             return;
19         else { // 否則交換父子內容再繼續子節點和孫節點比較
20             swap(&arr[dad], &arr[son]);
21             dad = son;
22             son = dad * 2 + 1;
23         }
24     }
25 }
26 
27 void heap_sort(int arr[], int len) {
28     int i;
29     // 初始化,i從最後一個父節點開始調整
30     for (i = len / 2 - 1; i >= 0; i--)
31         max_heapify(arr, i, len - 1);
32     // 先將第一個元素和已排好元素前一位做交換,再重新調整,直到排序完畢
33     for (i = len - 1; i > 0; i--) {
34         swap(&arr[0], &arr[i]);
35         max_heapify(arr, 0, i - 1);
36     }
37 }
38 
39 int main() {
40     int arr[] = { 3, 5, 3, 0, 8, 6, 1, 5, 8, 6, 2, 4, 9, 4, 7, 0, 1, 8, 9, 7, 3, 1, 2, 5, 9, 7, 4, 0, 2, 6 };
41     int len = (int) sizeof(arr) / sizeof(*arr);
42     heap_sort(arr, len);
43     int i;
44     for (i = 0; i < len; i++)
45         printf("%d ", arr[i]);
46     printf("\n");
47     return 0;

C++

 1 #include <iostream>
 2 #include <algorithm>
 3 using namespace std;
 4 
 5 void max_heapify(int arr[], int start, int end) {
 6     // 建立父節點指標和子節點指標
 7     int dad = start;
 8     int son = dad * 2 + 1;
 9     while (son <= end) { // 若子節點指標在範圍內才做比較
10         if (son + 1 <= end && arr[son] < arr[son + 1]) // 先比較兩個子節點大小,選擇最大的
11             son++;
12         if (arr[dad] > arr[son]) // 如果父節點大於子節點代表調整完畢,直接跳出函式
13             return;
14         else { // 否則交換父子內容再繼續子節點和孫節點比較
15             swap(arr[dad], arr[son]);
16             dad = son;
17             son = dad * 2 + 1;
18         }
19     }
20 }
21 
22 void heap_sort(int arr[], int len) {
23     // 初始化,i從最後一個父節點開始調整
24     for (int i = len / 2 - 1; i >= 0; i--)
25         max_heapify(arr, i, len - 1);
26     // 先將第一個元素和已經排好的元素前一位做交換,再從新調整(剛調整的元素之前的元素),直到排序完畢
27     for (int i = len - 1; i > 0; i--) {
28         swap(arr[0], arr[i]);
29         max_heapify(arr, 0, i - 1);
30     }
31 }
32 
33 int main() {
34     int arr[] = { 3, 5, 3, 0, 8, 6, 1, 5, 8, 6, 2, 4, 9, 4, 7, 0, 1, 8, 9, 7, 3, 1, 2, 5, 9, 7, 4, 0, 2, 6 };
35     int len = (int) sizeof(arr) / sizeof(*arr);
36     heap_sort(arr, len);
37     for (int i = 0; i < len; i++)
38         cout << arr[i] << ' ';
39     cout << endl;
40     return 0;
41 }