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


    动图演示

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

    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("
    ");
    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 }
  • 相关阅读:
    AWK 学习手札, 转载自lovelyarry
    Perl 学习手札之一: introduction
    开发者必看:iOS应用审核的通关秘籍
    Perl 学习手札之三: General syntax
    Perl 学习手札之二: Guide to experienced programmers
    RepotService添加空格符
    CSMS2软件架构
    关于Oracle的动态查询
    CSMS2公共方法
    CSMS2绑定数据
  • 原文地址:https://www.cnblogs.com/wangchaoguo-li/p/14205994.html
Copyright © 2020-2023  润新知