【算法导论】排序 (二):堆排序

四、(1)堆排序

第一次听堆排序是在107lab听忠哥讲的,但是没讲怎么实现。那时刚看了数据结 构的二叉树,还以为要通过指针建立二叉树的方式来实现,觉得挺难的。

其实堆排序实现没有想象中 的那么难。

“堆”这个词最初是在堆排序中提出来的,但后来就逐渐指”废料收集储存区“,就像程 序设计语言Lisp和Java中所提供的设施那样。我们这里的堆数据结构不是废料收集存储区。

堆排序的 运行时间与归并排序一样为O(n lg n),  但是一种原地(in place)排序。

(二叉)堆数据结 构是一种数组对象,它可以被视为一棵完全二叉树。

对于一个数组arr[ ]={16,14,10,8,7,9,3,2,4,1}的 存储数据结构如下图:

在这个结构中,对于每一个根节点i ,要保证它都比他的子节点大

我们可以用一个数组A 【1...length【A】】来表示这个完全二叉树结构。 其中A【1】为根节点1

首先问题是求父节点、左 儿子、右儿子的坐标,通过观察我们可以用宏或者内联函数实现:

// 根据某节点下标i, 计算父节

点、左儿子、右儿子的下标
inline int Parent(int i) { return i>>1; }
inline int Left(int i) { return i<<1; }
inline int Right(int i) { return (i<<1)|1; } //位运算乘2后,结果是偶数所以最后一位一定是0, 

所以|1将会把最后一位变成1,从而实现加1的效果

无论是《C++ primer》还是《Effective C++》 ,都讲过宏的缺陷,用内联函数是个更好的选择。位运算做乘除的速度更快。

至于算法演示过程在 《算法导论》上讲得很详细,不再赘述。

堆排序过程需要以下三个函数:

1、Max-Heapify (A,i) : 保持堆的性质,让A【i】在最大堆中“下降”,使以i节点为根的字数成为最大树

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索数组
, 数据结构
, 排序
, 堆
, 堆排序
, 算法导论
, 节点
, 计算机科学导论
, 下标
, 二叉树排序
, 算法导论习题堆排序
, 一个
, 堆排序算法
堆排序实现
算法导论 快速排序、归并排序 算法导论、算法导论 堆排序、堆排序 java 算法导论、算法导论,以便于您获取更多的相关知识。

时间: 2024-10-01 14:59:47

【算法导论】排序 (二):堆排序的相关文章

【算法导论】排序(一)

虽然久闻大名,但第一次接触算法导论,是看了网易公开课MIT的<算法导论>课,记得 第一集就讲到了 插入排序和归并排序. 几个星期前也买了算法导论这本书,准备慢慢啃~ 这星期主要在看前两 部分,除了对于讲渐进时间.递归式分析这些东西感到云里雾里的,其它的都就 感觉越看越有觉得入 迷,果然不愧是一本经典之作 好吧,开始.本文主要是用C++把书中的算法实现,以及一些笔记. 一.插入排序. 插入算法的设计使用的是增量(incremental)方法:在排好子数组A[1..j- 1]后,将 元素A[ j]

【算法导论】排序算法总结

排序算法总结         从六月初开始看算法导论,陆陆续续看了有2个月了,但实际看的时间只有半个月左右.这期间都忙着找导师.期末考试,同时还回家修养了十来天.真正专心的看算法是在离家返校后,由于没有考试和作业的烦恼,天天都沉浸在算法中,感觉效率较高.这段时间学到的东西较多,下面来总结一下:         学到的排序算法可以分为两类:比较排序.非比较排序.(这些排序算法的详细介绍及c程序实现在本文末都给出了链接,欢迎参考与指正!)         比较排序有:插入排序法.合并排序法.堆排序法

算法速成(二)七大经典排序之选择排序

今天说的是选择排序,包括"直接选择排序"和"堆排序". 话说上次"冒泡排序"被快 排虐了,而且"快排"赢得了内库的重用,众兄弟自然眼红,非要找快排一比高下. 这不今天 就来了两兄弟找快排算账. 1.直接选择排序: 先上图: 说实话,直接选择排序最类似于人的本能思想,比如把大小不一的玩具让三岁小毛孩对大小 排个序, 那小孩首先会在这么多玩具中找到最小的放在第一位,然后找到次小的放在第二位, 以此类推...... ,小 孩子多聪明

【算法导论】计数排序

计数排序 比较排序:通过元素间的比较对序列进行排序的算法称为比较排序. 常见的比较排序算法有:冒泡排序法.插入排序法.合并排序法.快速排序法,堆排序法等等.任何比较排序法在最坏情况下的时间复杂度为O(nlogn).因此,合并排序和堆排序是渐进最优的. 非比较排序:用非比较的方法来进行排序的算法. 常见的非比较排序算法有:计数排序法.基数排序法.桶排序法.它们都是以线性时间运行的.由于是非比较的,因此下界O(nlogn)对它们是不适用的. 下面来讨论计数排序: 前提假设:序列的值域在0到k之间.

浅谈算法和数据结构 二 基本排序算法

本篇开始学习排序算法.排序与我们日常生活中息息相关,比如,我们要从电话簿中找到某个联系人首先会按照姓氏排序.买火车票会按照出发时间或者时长排序.买东西会按照销量或者好评度排序.查找文件会按照修改时间排序等等.在计算机程序设计中,排序和查找也是最基本的算法,很多其他的算法都是以排序算法为基础,在一般的数据处理或分析中,通常第一步就是进行排序,比如说二分查找,首先要对数据进行排序.在Donald Knuth 的计算机程序设计的艺术这四卷书中,有一卷是专门介绍排序和查找的. 排序的算法有很多,在维基百

[算法系列之二十八]并查集(不相交集合)

一 概述 并查集(Disjoint set或者Union-find set)是一种树型的数据结构,常用于处理一些不相交集合(Disjoint Sets)的合并及查询问题. 有一个联合-查找算法(union-find algorithm)定义了两个操作用于此数据结构: Find:确定元素属于哪一个子集.它可以被用来确定两个元素是否属于同一子集. Union:将两个子集合并成同一个集合. 因为它支持这两种操作,一个不相交集也常被称为联合-查找数据结构(union-find data structur

必须掌握的八种排序(3-4)--简单选择排序,堆排序

3.简单选择排序 (1)基本思想:在要排序的一组数中,选出最小的一个数与第一个位置的数交换: 然后在剩下的数当中再找最小的与第二个位置的数交换,如此循环到倒数第二个数和最后一个数比较为止. (2)理解图 第一次 : 08最小 和21交换位置 第二次: 除第一个位置的08外 16最小 和25交换位置 以此类推 (3)代码实现 public static void selectSort(int[] a) { int position = 0; for (int i = 0; i < a.length

基本数据结构(算法导论)与python

Stack, Queue Stack是后进先出, LIFO, 队列为先进先出, FIFO 在python中两者, 都可以简单的用list实现, 进, 用append() 出, Stack用pop(), Queue用pop(0), pop的时候注意判断len(l)  对于优先队列, 要用到前面讲到的堆 链表和多重数组 这些数据结构在python中就没有存在的价值, 用list都能轻松实现 散列表 为了满足实时查询的需求而产生的数据结构, 查询复杂度的期望是O(1), 最差为O(n) 问题描述, 对

算法之排序算法的算法思想和使用场景总结_C 语言

1. 概述 排序算法是计算机技术中最基本的算法,许多复杂算法都会用到排序.尽管各种排序算法都已被封装成库函数供程序员使用,但了解排序算法的思想和原理,对于编写高质量的软件,显得非常重要. 本文介绍了常见的排序算法,从算法思想,复杂度和使用场景等方面做了总结. 2. 几个概念 (1)排序稳定:如果两个数相同,对他们进行的排序结果为他们的相对顺序不变.例如A={1,2,1,2,1}这里排序之后是A = {1,1,1,2,2} 稳定就是排序后第一个1就是排序前的第一个1,第二个1就是排序前第二个1,第