堆排序

通常所说的堆是指二叉堆,其定义为:

n个元素的序列{k1,k2,…,kn}当且仅当满足下列关系时,被称为堆:ki <= k2i 并且 ki <= k2i+1 , 或者 ki >= k2i 并且 ki >= k2i+1。 若将此序列看成是一个完全二叉树,则二叉树中所有非叶子结点的值都不大于(或者不小于)其左、右孩子结点的值,父结点的值比较大的叫做最大堆(或者大根堆),父结点比较小的叫做最小堆(或者小根堆)。显而易见,在最大堆中,堆顶的元素最大,在最小堆中,堆顶的元素最小。堆排序就是利用大根堆的性质进行排序的一种算法,将数组建堆后,每次将堆顶元素(为最大元素)取出放置与数组的最后,再将除最大元素外的其余元素建堆,取出第二大元素...依此递归进行即可。

时间复杂度:O(n * logn)

稳定性:不稳定

实现:

   1: /*
   2:  * 假设k的左右子树满足大根堆性质, 使以k为根的子树成为大根堆
   3:  */
   4: void
   5: max_heapify(int a[], int n, int k)
   6: {    
   7:     int i;
   8:     int key = a[k];
   9:     
  10:     for (i = 2*k+1; i < n; i = i*2+1) {
  11:         if (i < n - 1 && a[i] < a[i+1])
  12:             ++i;
  13:         if (a[i] <= key)
  14:             break;
  15:         a[k] = a[i];
  16:         k = i;    
  17:     }
  18:     a[k] = key;
  19: }
  20:  
  21: void
  22: build_max_heap(int a[], int n)
  23: {
  24:     int i;
  25:     
  26:     for (i = n/2; i >= 0; --i) {
  27:         max_heapify(a, n, i);
  28:     }
  29: }
  30:  
  31: void
  32: heap_sort(int a[], int n)
  33: {
  34:     int i;
  35:  
  36:     build_max_heap(a, n);        
  37:     for (i = n - 1; i > 0; --i) {
  38:         swap(a[0], a[i]);
  39:         max_heapify(a, i, 0);
  40:     }
  41: }
  42:  
posted @ 2012-06-01 08:30  Newerth  阅读(253)  评论(0编辑  收藏  举报