zoukankan      html  css  js  c++  java
  • [算法 笔记]堆排序(续)

      上一篇有关堆排序的源码是从STL标准库中抽出来,但是源码有点让我混乱。最近闲来无事,再写一篇有关堆排序的博客,并附上简单的过程描述。

      (参考书籍:《算法引论 —— 一种创造性方法》 4.76.4.5

     

      堆排序最坏情况下的运行时间是O(n log n)。堆排序中建堆方式有两种:

      1. 自顶向下建立大根堆。简单点说,就是从无到有插入元素到堆中。这样可以有效地维护了大根堆的性质,即大根堆是由满足大根堆性质的子堆构成。

      2. 自底向上建立大根堆。一般都是从堆存储数组的一半的位置开始递减比较。需要注意的是,在每次比较后,需要调整子堆来满足大根堆的性质。有点类似于从建好的大根堆中移除元素之后的调整。(这种方式参考《数据结构(C语言版)》 严蔚敏,吴伟民著的10.4.3节)

      通过上述资料会发现,自顶向下建立大根堆的方式要比自底向上建立大根堆的方式简单。这里使用的是第一种方式:

     1 void build_heap( int heap[], int current_size )
     2 {
     3     int start = 0;
     4 
     5     while ( start < current_size - 1 )
     6     {
     7         // start在insert_to_heap函数会发生变化      
     8         insert_to_heap( heap, &start, start + 1, heap[start] );
     9     }
    10 }

      在建立堆之后,堆排序的处理:只需要将大根堆中的最大值(heap[0])从堆中移除,并将其插入到数组的末尾(升序方式)。

     

     1 void heap_sort( int heap[], int current_size )
     2 {
     3     int i = current_size - 1;
     4     int j = current_size;
     5 
     6     build_heap( heap, current_size );
     7     while ( j )
     8     {
     9         int data = remove_max_from_heap( heap, &j );
    10         heap[i] = data;
    11         --i;
    12     }
    13 }

     

      完整的源码:

      1 #include <stdio.h>
      2 #include <assert.h>
      3 
      4 void swap_value( int heap[], int lhs, int rhs )
      5 {
      6     int tmp = heap[lhs];
      7     heap[lhs] = heap[rhs];
      8     heap[rhs] = tmp;
      9 }
     10 
     11 /** @*current_size: 表示heap中已经存在的元素个数。
     12  ** @heap_size:表示heap的最大容量是多少
     13  */
     14 void insert_to_heap( int heap[], int *current_size,
     15                      int heap_size, const int value )
     16 {
     17     int child = *current_size;
     18     int parent = 0;
     19 
     20     assert( *current_size < heap_size );
     21     heap[child++] = value;
     22     parent = child / 2;
     23     while ( parent >= 0 )
     24     {
     25         if ( heap[child] > heap[parent] )
     26         {
     27             swap_value( heap, child, parent );
     28             child = parent;
     29             parent /= 2;
     30         }
     31         else
     32             parent = -1;
     33     }
     34     *current_size += 1;
     35 }
     36 
     37 int remove_max_from_heap( int heap[], int *current_size )
     38 {
     39     int result = 0;
     40     int child = 0;
     41     int parent = 0;
     42 
     43     if ( *current_size == 0 )
     44     {
     45         printf( "remove_max_from_heap: the heap is empty.
    " );
     46         return -1;
     47     }
     48 
     49     result = heap[0];
     50     swap_value( heap, 0, *current_size - 1 );
     51     --*current_size;
     52     child = 1;
     53     while ( child <= *current_size - 1 )
     54     {
     55         if ( child < *current_size - 1
     56             && heap[child] < heap[child + 1] )
     57         {
     58             child += 1;
     59         }
     60 
     61         if ( heap[child] > heap[parent] )
     62         {
     63             swap_value( heap, child, parent );
     64             parent = child;
     65             child *= 2;
     66         }
     67         else
     68         {
     69             child = *current_size;
     70         }
     71     }
     72 
     73     return result;
     74 }
     75 
     76 void build_heap( int heap[], int current_size )
     77 {
     78     int start = 0;
     79 
     80     while ( start < current_size - 1 )
     81     {
     82         insert_to_heap( heap, &start, start + 1, heap[start] );
     83     }
     84 }
     85 
     86 void heap_sort( int heap[], int current_size )
     87 {
     88     int i = current_size - 1;
     89     int j = current_size;
     90 
     91     build_heap( heap, current_size );
     92     while ( j )
     93     {
     94         int data = remove_max_from_heap( heap, &j );
     95         heap[i] = data;
     96         --i;
     97     }
     98 }
     99 
    100 int main()
    101 {
    102     int heap[] = { 78, 58, 87, 62, 92, 332, 55, 40, 75, 146 };
    103     int heap_size = sizeof(heap) / sizeof(int);
    104     int i = 0;
    105 
    106     heap_sort( heap, heap_size );
    107     while ( i < heap_size )
    108     {
    109         printf( "%d ", heap[i++] );
    110     }
    111 
    112 
    113     return 0;
    114 }
    View Code

     

  • 相关阅读:
    Java入门——(3)面对对象(下)
    Java入门——(8)网络编程
    Java入门——(2)面对对象(上)
    MAC下的Intellij IDEA常用快捷键
    RedHat安装yum+配置国内yum源
    XGBoost算法
    Bagging和Boosting 概念及区别
    关于python的sort和sorted
    sklearn中常用数据预处理方法
    安装Scala
  • 原文地址:https://www.cnblogs.com/life91/p/3393644.html
Copyright © 2011-2022 走看看