【算法】堆排序

实现堆排序算法 堆排序是指利用积树()这种数据结构所设计的一种排序算法,它是选择排序的一种。可以利用数组的特点快速定位指定索引的元素。分为大根和小根,是完全二叉树。大根的要求是每个节点的值都不大于其父节点的值。在数组的非降序排序中,需要使用的就是大根,因为根据大根的要求可知,最大的值一定在顶。 /** *    实验题目: *        实现堆排序算法 *    实验目的: *      ... 阅读详情

堆,是一种完全二叉树,分为最大堆最小堆(或者叫“大根堆” “小根堆”)。
最大堆即:每个父节点元素都大于等于其所有子节点元素。最小堆同理。

堆排序的第一步便是构造堆。构造堆有两个重要方法,即sink(下沉)swim(上浮)

sink & swim

假设目前又一个有序的最大堆,然后在index处插入一个元素,堆变的无序,为了使堆恢复有序,就要用到sinkswim方法,代码实现如下:

【声明】这里假设堆顶为0,所以第k个节点的子节点为2 * k + 12 * k + 2,父节点为(k % 2 == 0) ? ((k - 1) / 2) : (k / 2)

// 堆排序辅助方法————下沉(小元素下沉)
void sink(int *arr, int index, int len){
    int i;
    // index 的子节点为 (2 * index + 1) 和 (2 * index + 2)
    while(2 * index + 1 <= len - 1){
        i = 2 * index + 1;
        // 和最大的子节点交换
        if((i + 1 <= len - 1) && (arr[i] <= arr[i + 1]))
            i++;
        if(arr[index] >= arr[i])
            break;
        exchange(arr, index, i);
        index = i;
    }
}

方法sink的主要思想就是,比较父节点和子节点,并把该元素和最大的子节点交换,一直“沉”到适当的位置,这里是最大堆,所以把小元素“下沉”

// 堆排序辅助方法————上升(大元素上升)
void swim(int *arr, int index, int len){
    int i;
    while (index > 0) {
        i = (index % 2 == 0) ? ((index - 1) / 2) : (index / 2); // 父节点
        if(arr[index] <= arr[i])
            break;
        exchange(arr, index, i);
        index = i;
    }
}

swim则和sink相反,比较子节点和父节点,一直“浮”到适当的位置,这里是最大堆,所以把大元素“上浮”

构造堆

构造堆即通过sinkswim方法。

【注意】构造堆时,如果用sink法,就要从数组的一半位置向前迭代;如果用swim法就要从堆第二层(即第二个元素)开始向后迭代。

// sink构建最大堆
for(int i = len / 2 - 1; i >= 0; i--)
    sink(arr, i, len);
// swim构建最大堆
for(int i = 1; i < len; i++)
    swim(arr, i, len);

堆排序

堆排序第一步即是构造堆。构造堆后,即从最后一个元素开始,交换堆顶和堆的最后一个元素,因为是最大堆,所以此时堆的最后一个元素应为最大数,然后除去该数,即堆的大小减一,把堆顶sink下来,这样大小减一之后的堆就又变为有序的了。代码实现如下:

// 堆排序
void heapSort(int *arr, int len){

    // sink构建最大堆
    for(int i = len / 2 - 1; i >= 0; i--)
        sink(arr, i, len);

    // 下沉排序
    for(int i = len - 1; i >= 0; i--){
        exchange(arr, 0, i); // 交换堆顶和最后一位,最后一位即为最大数
        sink(arr, 0, i); // 将堆的大小减一,然后将换到堆顶的数”沉“下去
    }
}
堆排序算法的实现 1、什么是 “(二叉)是一个数组,它可以被看成一个近似的完全二叉树。树上的每一个节点对应数组中的一个元素。除了最底层外,该树是完全充满的,而且是从左到右填充”。这是算法导论里对的定义,说得很清晰明了,当然最好还是得上个图,所以这里就顺便也从算法导论里盗个图了。。。。 二叉可以分为两种形式,最大和最小。在这两种中,节点的值都要满足的性质,同时在最大中,除了根以外的所有节... 阅读详情

相关推荐

【python算法系列四】堆排序算法

堆排序,就像它的名字一样,利用了的特性来进行排序。实现堆排序的思路是,把数组构建成一棵二叉树,并随着每次的变化更新顶的最大/最小值。堆排序的时间复杂度在所有情况下都是 O(nlgn),它也是一个不稳定的算法。在开始编写堆排序的程序之前,我们首先要了解“”的概念。 是一种数据结构,它是一种特殊的完全二叉树:如果这个是一个大顶(最大的元素在顶),那么每个节点上的元素都应该比它的子节点上的元素要大,最大的元素在根节点上;反之,如果是小顶,那么每个节点上的元素都应该比它的子节点小,最小的元素在根节

m0_70372647的博客 2004

java_堆排序

堆排序 采用完全二叉树 由下至上的有序化(上浮) 如果的有序化,因为某个节点比它的父节点还要大而打破的有序化,那么该节点就要上浮,上浮的关键是,节点k的父节点为k/2。   由上至下的有序化(下沉) 如果某个节点因为变得比它的两个子节点之一要小,那么该节点就要下沉。将该节点与两个子节点中较大的节点进行交换来恢复。下沉的关键是将节点k与它的子节点2k或2k+1交换。   插入

hlang8160的博客 349

VMware + ubuntu20.04 + qemu安装

遇到报错可参考:(从ubuntu裸系统开始安装)

NosONE 3199

堆排序详解

上一篇博文大概讲述了优先级队列的实现,这一篇来谈一下堆排序,优先级队列参考如下博文。详解二叉,及优先级队列实现​​​​​​ 上述博文中介绍了完全二叉树,满二叉树,的存储,以及介绍了优先级队列的一些实现,这一篇博文来介绍下堆排序相关的内容。 上文中提供了一些常用的方法,如插入一个元素时,为了维持的特性需要执行上浮(swim)方法,以及删除一个元素时为了维持的性质而执行的下沉(sink)方法。以及一些如求左孩子left方法,和求右孩子right......

码农笔记 327

算法系列—堆排序

堆排序可以分为两个阶段 得构造阶段,我们将原始数组重新组织安排进一个中 下沉排序阶段,从中按顺序取出所有元素并得到排序结果 PS:此处堆排序,数组下标是从1开始,0位置不存储。 #include #include void sink(int A[], int k, int size); void HeapSort(int A[], int size) { int N

candy_xiaolei的博客 355

【alg4-排序】堆排序

堆排序可以分为两个阶段。在的构造阶段中,我们将原始数组重新组织安排进一个中;然后在下沉排序阶段,我们从中按递减顺序取出所有元素并得到排序结果。 的构造:从右至左用sink()函数构造子。数组的每个位置都已经是一个子的根结点了,sink()对于这些子也适用。如果一个结点的两个子结点都已经是了,那么在该结点上调用sink()可以将它们变成一个。这个过程会递归地建立起的秩序。开始时我们只需要扫描数组中的一半元素,因为我们可以跳过大小为1的子。最后我们在位置1上调用sink()方法,扫描结束。

... 267

算法4》中的堆排序

堆排序

markjenny的博客 2044

堆排序算法

一、堆排序算法基本思想 堆排序是利用数据结构而设计的一种排序算法堆排序是一种选择排序,其最坏,最好,平均时间复杂度均为O(nlogn),同时也是不稳定排序。 是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶, 如下图所示,其中大顶的性质**:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2]** 每个结点的值都小于或等于其左右孩子结点的值,称为小顶,如下图所示,其中小顶性质:arr[i] <=

qq_44111805的博客 7379

必学排序算法——堆排序

堆排序算法是必须掌握的一种基础算法,在一些比较出名的竞赛acm、蓝桥杯,并且在一些公司面试题中都可能会出现,而且作为简单题我们必须要拿下,所以我们要引起重视,下面让我们来深入了解堆排序算法堆排序(Heap Sort)是一种基于数据结构的比较排序算法是一个近似完全二叉树的结构,分为最大和最小。在最大中,父节点的值总是大于或等于其子节点的值;而在最小中,父节点的值总是小于或等于其子节点的值。堆排序通常使用最大来升序排序数组,使用最小则可以降序排序数组。

ycs66的博客 3809

[算法沉淀记录] 排序算法 —— 堆排序

堆排序(Heap Sort)是一种基于比较的排序算法,它利用这种数据结构来实现排序。是一种特殊的完全二叉树,其中每个节点的值都必须大于或等于(最大)或小于或等于(最小)其子节点的值。是一个近似完全二叉树的数据结构,满足任一非叶子节点的值不小于(或不大于)其左右孩子节点的值。通常分为最大和最小堆排序算法通过构建一个最大或最小,然后将顶元素(最大或最小值)与的最后一个元素交换,再将剩余的元素重新调整为最大或最小,如此反复,直到整个数组有序。堆排序是一种高效的排序算法

莫寒技术人生 1710

堆排序堆排序算法

堆排序概念 堆排序,将数组当作二叉树的形式进行排序,根据排序的不同形式分为大顶与小顶 并且是一颗完全二叉树(不是满二叉树) 完全二叉树 满二叉树 堆排序后的数组性质 其排序的二叉树后满足如下条件(以大顶进行举例) 每个节点(包括根节点)的子节点及其所有子节点均`小于`该节点(即在他下面的全部都比他小,不管是否是直接子节点) 由于是数组来表示树的结构,所以满足如下性质 //此处将数组下标为0的位置不使用 //如果非要使用下标0的单元,则以下的性质与算法需要根据实际使用进行减去相差位数 根节点为数组第

weixin_44019654的博客 360

为什么用sink()方法构造比swim()方法效率高

用sikn()方法构造时,是从二叉树的倒数第二层开始sink, 即 可以跳过大小为1的子。 而最后一层的节点个数为N/2, 所以我们只需数组中的一半元素执行sink方法。  ...

Pyrrhax的博客 726

算法6.堆排序

: 二叉满足二个特性: 1.父结点的键值总是大于或等于(小于或等于)任何一个子节点的键值。 2.每个结点的左子树和右子树都是一个二叉(都是最大或最小)。 当父结点的键值总是大于或等于任何一个子节点的键值时为最大。当父结点的键值总是小于或等于任何一个子节点的键值时为最小。 一般用数组实现二叉 当下标是i,左孩2*i+1,右孩2*i+2,父节点(i-1)/2,第一个非叶节点...

speargod的博客 353

算法(第四版)》排序-----堆排序

1.什么是? 讲堆排序之前,先了解一下什么是其实相当于一种数据结构,它的本质是一种数组对象,但是它里面的内同又是一颗完全二叉树结构,它的特点是父节点的值大于(或小于)两个子节点的值,常常用于优先队列、堆排序等。 在数组中的索引有如下的特点。数组索引为k的元素,它的父节点的索引为[k/2](下取整),它的两个子节点索引为2k, 2k+1,依次类推 2.堆排序的基本过程 (1

kwang0131的博客 1755

算法----堆排序(heap sort)

堆排序是利用进行排序的高效算法,其能实现O(NlogN)的排序时间复杂度,具体算法分析可以点击堆排序算法时间复杂度分析。 算法实现: 调整: void sort::sink(int* a, const int root, const int end) { int i=root; while(2*i +1 <= end) { int k = 2*i+1; if(k+1<=e

Leon_THU的专栏 1351

堆排序(heap sort)

前言 在学习堆排序之前,你需要先了解堆排序中需要用到许多前面二叉的操作,如果不知道可以看看我的前一个博客。https://blog.csdn.net/qq_39747794/article/details/82055919 堆排序 主要步骤: 1. 先将数列构建为二叉树,使每一个子节点都小于它的的父节点。这样根节点将是二叉中值最大的节点。 2. 将根节点与二叉中的末节点交换...

qq_39747794的博客 276

100天精通Python(基础篇)——第4天:数据类型全解析_从基础到转换

数据类型全解析_从基础到转换

努力让自己发光,对的人才能迎着光而来 11万+

MATLAB做的图像边缘检测界面

相关文章:http://blog.csdn.net/poonjun/archive/2009/01/04/3701881.aspx有疑问,请在我的博客:http://blog.csdn.net/poonjun留言

上一篇: 【PAT】 A1005. Spell It Right (20)
下一篇: 【前端】web安全字体
lilydedbb
博客等级 码龄10年 9粉丝 45原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值