花了些时间好好看了堆排序的内容,代码也敲了,现在来总结一下。

为了说明白点,有些图片我就从网上截取了。

首先是堆的概念。

数据结构中的堆,又叫二叉堆

一般用数组来表示堆得结构,或者说是把堆数组化。举个列子来看:

这样就很清楚的看出了堆的储存结构。

接着就是堆得操作处理了。

首先堆的插入操作:

上代码:

 1 void Heap_insert_fix(int a[],int n)
 2 {
 3      int temp;
 4      int i,j;
 5      i = n;
 6      j = (i - 1) / 2;/*父节点*/
 7      temp = a[i];/*记录插入的数据*/
 8      while(i != 0 && j >= 0)
 9      {
10             if(a[j] <= temp)
11                     break;
12             a[i] = a[j];
13             i = j;
14             j = (i - 1) / 2;
15      }
16      a[i] = temp;
17 }

上面代码解析:

先明白这点,

*父节点 i 子节点则为  j = i*2 +1
*子节点 i 父节点则为  j = (i-1) / 2

然后,插入的流程是,每次插入的数据都是在叶子节点,接着调整。直到满足堆得性质为止!

然后是堆的删除操作:

原理:每次删除根节点,就是用叶子节点覆盖根节点

上代码:

 1 /*
 2 *删除操作
 3 *删除根结点,然后调整
 4 *从i节点开始,总数有n个
 5 */
 6 void Heap_del_fix(int a[],int i,int n)
 7 {
 8     int j;
 9     int temp;
10     temp = a[i];
11     j = i * 2 + 1;/*子节点*/
12     while(j < n)
13     {
14          if(a[j] > a[j+1] && j+1 < n)
15          j++;
16          if(a[j] >= temp)
17          break;
18          a[i] = a[j];
19          i = j;
20          j = i*2 + 1;
21     }
22     a[i] = temp;
23 }

它的调用函数:

1 /*
2 *调用
3 */
4 void Heap_sub(int a[],int n)
5 {
6      swap(&a[0],&a[n-1]);
7      Heap_del_fix(a,0,n-1);
8 }

有了上面这两个操作的基础,下面我就来写排序操作!

思想:

我们有了删除操作,每次删除根节点,而且我们知道根节点是数组中数值最小的那个值(我这里是小堆模式,大堆相反),这样我们一次次的删除,就形成了一个有序的序列。获取这个序列就是我们想要的堆排序结果。

怎么获取,使用数组,看代码:

 1 /*
 2 *堆排序
 3 */
 4 void Heap_sort(int a[],int n)
 5 {
 6      int i;
 7      for(i=n-1;i>=1;i--)
 8      {
 9           swap(&a[0],&a[i]);
10           Heap_del_fix(a,0,i);
11      }
12 }

这样倒序便是我们的序列。

至于如何将堆数组化,代码如下:

 1 /*
 2 *堆化数组
 3 */
 4 void create_heap(int a[], int n)
 5 {
 6      int i;
 7      for(i=n/2-1;i>=0;i--)/*将数组转成堆,分开调整*/
 8      {
 9           Heap_del_fix(a,i,n);
10      }
11 }

这里的i=n/2-1;我们最好画图来看,这样理解会容易些。这部分我是在纸上实现的,读者可以自己尝试。

对于swap函数,一个比较好的写法如下:

1 void swap(int *i,int *j)
2 {
3      *i = *i ^ *j;
4      *j = *i ^ *j;
5      *i = *i ^ *j;
6 }

异或来交换两个数的写法,不需额外的变量。

整体代码如下:

  1 /*
  2 *堆排序
  3 *丁洋
  4 *说明:堆用数组来表示,那么
  5 *父节点 i 子节点则为  j = i*2 +1
  6 *子节点 i 父节点则为  j = (i-1) / 2
  7 *
  8 */
  9 #include<stdio.h>
 10 #include<stdlib.h>
 11
 12 void swap(int *i,int *j)
 13 {
 14      *i = *i ^ *j;
 15      *j = *i ^ *j;
 16      *i = *i ^ *j;
 17 }
 18 /*
 19 *插入操作
 20 *堆尾插入,然后调整
 21 */
 22 void Heap_insert_fix(int a[],int n)
 23 {
 24      int temp;
 25      int i,j;
 26      i = n;
 27      j = (i - 1) / 2;/*父节点*/
 28      temp = a[i];/*记录插入的数据*/
 29      while(i != 0 && j >= 0)
 30      {
 31             if(a[j] <= temp)
 32                     break;
 33             a[i] = a[j];
 34             i = j;
 35             j = (i - 1) / 2;
 36      }
 37      a[i] = temp;
 38 }
 39 /*
 40 *调用
 41 */
 42 void Heap_add(int a[],int n,int Num)
 43 {
 44      a[n] = Num;
 45      Heap_insert_fix(a,n);
 46 }
 47
 48 /*
 49 *删除操作
 50 *删除根结点,然后调整
 51 *从i节点开始,总数有n个
 52 */
 53 void Heap_del_fix(int a[],int i,int n)
 54 {
 55     int j;
 56     int temp;
 57     temp = a[i];
 58     j = i * 2 + 1;/*子节点*/
 59     while(j < n)
 60     {
 61          if(a[j] > a[j+1] && j+1 < n)
 62          j++;
 63          if(a[j] >= temp)
 64          break;
 65          a[i] = a[j];
 66          i = j;
 67          j = i*2 + 1;
 68     }
 69     a[i] = temp;
 70 }
 71 /*
 72 *调用
 73 */
 74 void Heap_sub(int a[],int n)
 75 {
 76      swap(&a[0],&a[n-1]);
 77      Heap_del_fix(a,0,n-1);
 78 }
 79
 80 /*
 81 *堆化数组
 82 */
 83 void create_heap(int a[], int n)
 84 {
 85      int i;
 86      for(i=n/2-1;i>=0;i--)/*将数组转成堆,分开调整*/
 87      {
 88           Heap_del_fix(a,i,n);
 89      }
 90 }
 91
 92 /*
 93 *堆排序
 94 */
 95 void Heap_sort(int a[],int n)
 96 {
 97      int i;
 98      for(i=n-1;i>=1;i--)
 99      {
100           swap(&a[0],&a[i]);
101           Heap_del_fix(a,0,i);
102      }
103 }
104 int main()
105 {
106     int i;
107     int a[] = {2,4,8,1};
108
109     create_heap(a,4);
110     Heap_sort(a,4);
111     for(i=0;i<4;i++)
112         printf("%d ",a[i]);
113     printf("\n");
114     system("pause");
115 }

时间复杂度:

由于每次重新恢复堆的时间复杂度为O(logN),共N - 1次重新恢复堆操作,再加上前面建立堆时N / 2次向下调整,每次调整时间复杂度也为O(logN)。二次操作时间相加还是O(N * logN)。故堆排序的时间复杂度为O(N * logN)。STL也实现了堆的相关函数,可以参阅《STL系列之四 heap 堆》

转载于:https://www.cnblogs.com/my-life/p/3489808.html

经典算法系列三----堆排序相关推荐

  1. 白话经典算法系列之七 堆与堆排序

     堆排序与高速排序,归并排序一样都是时间复杂度为O(N*logN)的几种常见排序方法.学习堆排序前,先解说下什么是数据结构中的二叉堆. 二叉堆的定义 二叉堆是全然二叉树或者是近似全然二叉树. 二叉堆满 ...

  2. 三白话经典算法系列 Shell排序实现

    山是包插入的精髓排序排序,这种方法,也被称为窄增量排序.因为DL.Shell至1959提出命名. 该方法的基本思想是:先将整个待排元素序列切割成若干个子序列(由相隔某个"增量"的元 ...

  3. 白话经典算法系列之——希尔排序的实现

    希尔排序的实质就是分组插入排序,该方法又称缩小增量排序,因DL.Shell于1959年提出而得名. 该方法的基本思想是:先将整个待排元素序列分割成若干个子序列(由相隔某个"增量"的 ...

  4. 机器学习经典算法(三)--指数加权平均

    机器学习经典算法(三)–指数加权平均 指数加权平均(Exponentially Weighted Averages)是一些改进梯度下降法重要理论,如上篇博文梯度下降法(2)提到的动量梯度下降法,RMS ...

  5. 【算法系列 三】 Quene

    为什么80%的码农都做不了架构师?>>>    1. 拓扑排序问题(HDU 1285) import java.io.BufferedReader; import java.io.I ...

  6. 【华为云技术分享】MongoDB经典故障系列三:副本集延迟太高怎么办?

    MongoDB副本集延迟太高,数据读取时间过长怎么办?不要慌,菊长教您一个小妙招:在集合创建的时候,就建立好索引,然后按照索引去寻找您所需要的数据.如果觉得比较麻烦,华为云文档数据库服务DDS了解一下 ...

  7. 白话经典算法系列之中的一个 冒泡排序的三种实现

    冒泡排序是很easy理解和实现,,以从小到大排序举例: 设数组长度为N. 1.比較相邻的前后二个数据,假设前面数据大于后面的数据,就将二个数据交换. 2.这样对数组的第0个数据到N-1个数据进行一次遍 ...

  8. 白话经典算法系列之一 冒泡排序的三种实现

    http://blog.csdn.net/morewindows/article/details/6657829 冒泡排序是非常容易理解和实现,,以从小到大排序举例: 设数组长度为N. 1.比较相邻的 ...

  9. raptor五个数排序流程图_经典算法系列之:选择排序

    1.前言 算法,在计算机中的地位,就相当于人类大脑的决策中枢系统,哪怕最简单的算法,其精妙的思维方式,都可以让人开启一扇新的视窗. 算法,它不仅仅只是狭义的用来解决计算机科学领域的问题,更是一种&qu ...

最新文章

  1. 【Android】Android中判断后台服务是否正在运行
  2. Centos netperf安装
  3. Javascript Symbol 隐匿的未来之星
  4. IOS 2D游戏开发框架 SpriteKit--续(创建敌对精灵)
  5. Redis Cluster原理初步
  6. CF476D-Dreamoon and Sets【结论】
  7. java bufferarray_Java中的ByteBuffer array()方法
  8. android 原生开发 3d地图 下载_arcgis api 3.x for js 入门开发系列二不同地图服务展示(附源码下载)...
  9. AWVS扫描器使用入门
  10. python将json转化为数组_将JSON转换为数组?
  11. HTML5-单、多选框,按钮
  12. mrpt在win8.1 64bit + vs2013环境下的安装和编译
  13. 如何将webp格式转换成png?
  14. 腾讯的星星海服务器芯片,腾讯云星星海重磅发布两款自研新品 打造软硬一体云计算基础设施...
  15. 判断已知顺序的三个点是顺时针还是逆时针
  16. php微云上传,API - 微云
  17. 笔记本电脑换新硬盘重装系统经验
  18. C语言从入门到精通第17天(指针和数组联用)
  19. Linux26期 6月21日
  20. 原生js获取本地ip地址(自己用)

热门文章

  1. “3D几何与视觉技术”全球在线研讨会(9月2日到12月16日)
  2. 内推|百度2020春实习-计算机视觉算法研发工程师-北京
  3. IoU-aware的目标检测,显著提高定位精度
  4. python爬虫实战教程分享 或许你可以看一下这篇文章
  5. 南邮linux期末考试试题,南邮操作系统试卷及答案.doc
  6. 目标跟踪算法综述:Correlation Filter for UAV-Based Aerial Tracking: A Review and Experimental Evaluation
  7. php com(),php|luosimao.com文档中心
  8. 图像分割总体介绍——深度AI科普团队
  9. 今日头条面试题:生成随机数(根据rand5()生成rand7())
  10. 一篇关于《1984》读后感