在路上

不是专业,只会通俗

导航

排序算法_堆排序

一、什么是堆

  堆可以视为一棵完全的二叉树,完全二叉树的一个“优秀”的性质是,除了最底层之外,每一层都是满的,这使得堆可以利用数组来表示,每一个结点对应数组中的一个元素.

  数组与堆之间的关系:

      

  

  • 父节点i的左子节点在位置 (2*i+1);
  • 父节点i的右子节点在位置 (2*i+2);
  • 子节点i的父节点在位置 [i/2];

二、分类

  最大堆:子结点的键值或索引总是小于它的父节点。

  最小堆:子结点的键值或索引总是大于它的父节点。

          

三、算法描述

  1. 堆排序就是把堆顶的最大数取出。
  2. 将剩余的堆继续调整为最大堆。
  3. 再次将堆顶的最大数取出,直到剩余数只有一个时结束。

四、性能描述

    数据结构 :数组

  最差时间复杂度 :O(nlogn)

  最优时间复杂度 :O(nlogn)

  平均时间复杂度 :O(nlogn)

  最差空间复杂度 :О(n) 

五、图示

  

六、C++语言实现代码

View Code
 1 #include <iostream>
 2 using namespace std;
 3 /*
 4         #堆排序#%
 5           #数组实现#%
 6 */
 7 //#筛选算法#%
 8 void sift(int d[], int ind, int len)
 9 {
10         //#置i为要筛选的节点#%
11         int i = ind;
12  
13         //#c中保存i节点的左孩子#%
14         int c = i * 2 + 1; //#+1的目的就是为了解决节点从0开始而他的左孩子一直为0的问题#%
15  
16         while(c < len)//#未筛选到叶子节点#%
17         {
18                 //#如果要筛选的节点既有左孩子又有右孩子并且左孩子值小于右孩子#%
19                 //#从二者中选出较大的并记录#%
20                 if(c + 1 < len && d[c] < d[c + 1])
21                         c++;
22                 //#如果要筛选的节点中的值大于左右孩子的较大者则退出#%
23                 if(d[i] > d[c]) break;
24                 else
25                 {
26                         //#交换#%
27                         int t = d[c];
28                         d[c] = d[i];
29                         d[i] = t;
30                         //
31                         //#重置要筛选的节点和要筛选的左孩子#%
32                         i = c;
33                         c = 2 * i + 1;
34                 }
35         }
36  
37         return;
38 }
39  
40 void heap_sort(int d[], int n)
41 {
42         //#初始化建堆, i从最后一个非叶子节点开始#%
43         for(int i = n / 2; i >= 0; i--)
44                 sift(d, i, n);
45  
46         for(int j = 0; j < n; j++)
47         {
48                 //#交换#%
49                 int t = d[0];
50                 d[0] = d[n - j - 1];
51                 d[n - j - 1] = t;
52  
53                 //#筛选编号为0 #%
54                 sift(d, 0, n - j - 1);
55  
56         }
57 }
58  
59 int main()
60 {
61         int a[] = {3, 5, 3, 6, 4, 7, 5, 7, 4}; //#QQ#%
62  
63         heap_sort(a, sizeof(a) / sizeof(*a));
64  
65         for(int i = 0; i < sizeof(a) / sizeof(*a); i++)
66         {
67                 cout << a[i] << ' ';
68         }
69         cout << endl;
70     return 0;
71 }

 

 

 参考文档:

  1. 堆排序_百度百科 

    http://baike.baidu.com/view/157305.htm

  2. 堆排序原理图解

    http://blog.csdn.net/jokers_i/article/details/8180533

  3. 堆積排序

    http://zh.wikipedia.org/zh-cn/堆積排序

posted on 2013-01-16 19:00  OnRoad_  阅读(573)  评论(0编辑  收藏  举报