• 堆以及堆排序详解


    记录一下自己理解的堆和堆排序吧。

    堆是一种类似于完全二叉树的树形结构,对于二叉树中所有非叶子节点,如果根节点的值严格大于其两个儿子的值,则称为

    大顶堆,反之称为小顶堆。

    堆排序的一般步骤:

      首先利用已有的数据构造一个堆,大顶堆增序,小顶堆降序。

      将堆顶的元素与堆末元素交换,接着重新调整剩下的元素为一个堆,直到堆末等于堆顶,则堆排序结束。

      如何把无序数组建堆。

      首先说明一个下沉调整法。

      言下之意就是对于一个节点,如果其存在值大于此节点值的儿子,就交换他们,并对这个儿子节点再进行调整。

      对于一个长度为n的无序数组,如果下标从1 ~ n,那么必定仅有n / 2个结点有子节点。我们从第n / 2个结点开始将其和前面

    所有节点进行下沉调整,即得到一个堆。

    大顶堆升序排序:

     1 #include <cstdio>
     2 using namespace std;
     3 
     4 const int maxn = 100 + 5;
     5 int val[maxn];
     6 
     7 void swap(int a, int b) {
     8     int t = val[a];
     9     val[a] = val[b];
    10     val[b] = t;
    11 }
    12 
    13 void sink(int n, int i) {
    14     int max = i;
    15     int l = i << 1, r = i << 1 | 1;
    16     if(l <= n && val[l] > val[max]) max = l;
    17     if(r <= n && val[r] > val[max]) max = r;
    18     if(max != i) {
    19         swap(max, i);
    20         sink(n, max);
    21     }
    22 }
    23 
    24 void heap_sort(int n) {
    25     for(int i = n / 2; i >= 1; i --) {
    26         sink(n, i);
    27     }
    28     for(int i = n; i > 1; i --) {
    29         swap(1, i);
    30         //printf("%d %d
    ", val[1], val[i]);
    31         sink(i - 1, 1);
    32     }
    33 }
    34 
    35 int main() {
    36     int n;
    37     scanf("%d", &n);
    38     for(int i = 1; i <= n; i ++) {
    39         scanf("%d", &val[i]);
    40     }
    41     heap_sort(n);
    42     for(int i = 1; i <= n; i ++) {
    43         printf("%d ", val[i]);
    44     }
    45     puts("");
    46     return 0;
    47 }

    小顶堆降序排序:

    其实就是把sink函数中的大于号变成小于号了而已。

     1 #include <cstdio>
     2 using namespace std;
     3 
     4 const int maxn = 100 + 5;
     5 int val[maxn];
     6 
     7 void swap(int a, int b) {
     8     int t = val[a];
     9     val[a] = val[b];
    10     val[b] = t;
    11 }
    12 
    13 void sink(int n, int i) {
    14     int min = i;
    15     int l = i << 1, r = i << 1 | 1;
    16     if(l <= n && val[l] < val[min]) min = l;
    17     if(r <= n && val[r] < val[min]) min = r;
    18     if(min != i) {
    19         swap(min, i);
    20         sink(n, min);
    21     }
    22 }
    23 
    24 void heap_sort(int n) {
    25     for(int i = n / 2; i >= 1; i --) {
    26         sink(n, i);
    27     }
    28     for(int i = n; i > 1; i --) {
    29         swap(1, i);
    30         sink(i - 1, 1);
    31     }
    32 }
    33 
    34 int main() {
    35     int n;
    36     scanf("%d", &n);
    37     for(int i = 1; i <= n; i ++) {
    38         scanf("%d", &val[i]);
    39     }
    40     heap_sort(n);
    41     for(int i = 1; i <= n; i ++) {
    42         printf("%d ", val[i]);
    43     }
    44     puts("");
    45     return 0;
    46 }
  • 相关阅读:
    horizontal line and right way to code it in html, css
    Inline vs. block-level elements: a demonstration
    How wide is the default `<body>` margin?
    Getting wrong Version from Assembly using Reflection
    Where is the default size of a div element defined or calculated?
    Why padding is included in height sometimes?
    动态分析Android App之动态调试
    学习: Linux的 date 命令
    一个有趣的安全分析场景DSL设计
    Beats Elastic中的Auditbeat使用介绍
  • 原文地址:https://www.cnblogs.com/bianjunting/p/13178956.html
Copyright © 2020-2023  润新知