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

动图演示

堆排序可以说是一种利用堆的概念来排序的选择排序。分为两种方法:

  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 }

 

posted @ 2020-12-29 13:24  梓涵VV  阅读(110)  评论(0编辑  收藏  举报