堆排序

什么是堆排序 堆排序是使用二叉堆这样强大的数据结构来实现的排序 回顾:二叉堆的特性 二叉堆本质上是一种完全二叉树 最大堆(最小堆)的堆顶是整个堆中的最大(最小)元素 原理 当我们删除一个最小堆的堆顶的时候是把堆顶的元素删除,并把最后一个元素拿到堆顶 这时如果我们不把堆顶元素删除,而是把堆顶和最后一个元素替换,并把堆的有效长度减1 之后向下调整67,使堆保持稳定 重复上述操作将现在有效长度内的最后... 阅读详情

学习之后,自己练习手写一下排序算法,加深印象

原理:将待排序n个元素的序列构造成一个大顶堆。此时,整个序列的最大值就是堆顶的根结点。将它与堆末尾的元素交换后,移除。然后将剩下n-1个元素的序列重新构造成一个堆,这样就会得到这n-1个元素中最大值。如此反复交换根结点和构建新的堆,便能得到一个有序序列。

堆排序用到了完全二叉树的概念和性质,参见我的笔记https://blog.youkuaiyun.com/zjw_python/article/details/72808518
即若按照层序遍历的方式给结点编号,那么结点i的左孩子为2i,右孩子为2i+1。(如果有左右孩子)

堆(Heap)是具有下列性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆;或者每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆

如何构造大顶堆呢?从下往上,从右到左,将每个非终端结点当做根结点,将其和其子树调整为大顶堆,我们先假设一个函数HeapAdjust(*L, int s, int maxIndex),其作用就是将序列中某个不符合堆结构的结点及其子树调整为堆结构,L为传入的序列指针,s为某个不满足堆结构的节点索引,maxIndex为序列的最大索引。

堆排序的代码

HeapSort(struct a *L){
    for (i = L->length/2; i>=1; i--){  //初始化序列为一个大顶堆,i等于n/2,因为
        HeapAdjust(L, i, L->length);   //包含n个元素的完全二叉树,拥有孩子结点的结点个数小于或等于⌊n/2⌋
    }

    for (i=L->length; i>1; i--){
        swap(L, 1, i);   //交换堆的根结点和最末端的结点
        HeapAdjust(L, 1, i-1);   //移除最末端的结点,重新调整为大顶堆
    }
}
HeapAjust(struct a *L, int s, int maxIndex){
    int j,temp;
    temp = L->array[s];   //先将该不符合堆结构结点的值暂存起来
    for (j=2*s; j<=maxIndex; j*=2){  //从该结点的左子节点开始,所以i=2*s,而节点的节点是以2的倍数增加的
        if (j<maxIndex && L->array[j] < L->array[j+1]){   //比较左孩子结点和右孩子结点谁的值更大
            j++;                               //j为具有更大值孩子节点的索引
        }
        if (temp > L->array[j]){     //如果当前结点的值比左右两孩子结点的值都要大
            break;               //说明当前结点符合堆结构,则退出循环
        }
        L->array[s] = L->array[j];   //将当前结点的值替换为左右孩子结点中更大的值
        s = j;                       //将当前结点替换为孩子结点,以该孩子结点为根结点,重新循坏
    }
    L->array[s] = temp;      //找到用于放置不符合堆结构的结点值的位置,替换之
}

完整的代码

#define MAXSIZE 10
#include <stdio.h>
struct a{
    int array[MAXSIZE];    //数组用于存储排序数据 
    int length;           //用于存储数组长度信息, 
};

void init_array(struct a *L){   //初始化数组 
    int i;
    L->length = MAXSIZE-1;
    for (i=1;i<=L->length;i++){     //索引为0的项留作备用 
        scanf("%d",&(L->array[i]));
    }
}

void swap(struct a *L,int i,int j){   //交换数组项 
    int temp = L->array[i];
    L->array[i] = L->array[j];
    L->array[j] = temp;
}

void print(struct a *L){    //打印数组项 
    int i;
    for (i=1;i<=L->length;i++){
        printf("%d ",L->array[i]);
    }
}

void HeapAdjust(struct a *L, int s, int maxIndex){
    int j,temp;
    temp = L->array[s];
    for (j=2*s; j <= maxIndex; j*=2){
        if (j<maxIndex && L->array[j] < L->array[j+1]){
            j++;
        }

        if (temp > L->array[j]){
            break;
        }

        L->array[s] = L->array[j];
        s = j;
    }
    L->array[s] = temp;
    printf("\n构建堆:"); 
    print(L);
}

void HeapSort(struct a *L){   //排序算法 
    int i;
    for (i= L->length/2; i>=1; i--){
        HeapAdjust(L,i,L->length);
    }

    for (i=L->length; i>1; i--){
        swap(L,1,i);
        HeapAdjust(L,1,i-1);
    }
} 

int main(){
    struct a List;
    init_array(&List);
    printf("排序前:");
    print(&List);
    HeapSort(&List);
    printf("\n排序后:");
    print(&List);
    return 0;
}

这里写图片描述

算法时间复杂度:O(nlogn)

Python 爬虫实战:爬取豆瓣读书评论并分析 摘要:本文以豆瓣读书《活着》评论数据为例,详细讲解Python爬虫开发与文本分析全流程。首先通过requests库爬取评论数据,解决分页、反爬等问题;然后利用BeautifulSoup解析页面提取评论内容、评分等核心信息;最后结合jieba进行关键词提取、snownlp完成情感分析,并通过可视化展示结果。分析显示该书评分以5星为主(占比70%),正面评论达82%,核心关键词为"活着""余华""生命"。全文包含完整代码与详细解析,帮助读者掌握非结构化 阅读详情

相关推荐

Python RPA 流程自动化快速上手

Python RPA 流程自动化快速上手

看花容易绣花难 1万+

手写堆排序算法

堆排序算法,是通过堆这种数据结构来实现排序。 堆,其实就是二叉树。由于排序有从小到大、从大到小两种排序方式,对应的堆也分为最小堆和最大堆。 最小堆,就是一颗完全二叉树,每个节点都比其左子节点和右子节点小,整个树的根节点最小。 最大堆,就是一颗完全二叉树,每个节点都比其左子节点和右子节点大,整个树的根节点最大。 用一个连续的数组内存空间,就能表示堆。如下图所示: ​数组中每个元素,代表最小(大)堆中的一个节点,每个节点最多有两个子节点: 左子节点和右子节点。 上图中的箭头,是从父节点指向.

实力程序员 582

NTU RGB + D 120 动作识别数据集 描绘骨架(python)

“ NTU RGB + D”和“ NTU RGB + D 120”。 “ NTU RGB + D”包含60个动作类别和56,880个视频样本。 “ NTU RGB + D 120”通过添加另外60类和另外57,600个视频样本来扩展“ NTU RGB + D”,即“ NTU RGB + D 120”总共有120类和114,480个样本。 这两个数据集都包含每个样本的RGB视频,深度图序列,3D骨骼...

单线程的Daniel的博客 1万+

堆排序(手写堆)

堆排序(手写堆)(后续待更新)

weixin_67693658的博客 688

[Ethernet in CANoe]4--CANoe工程中SOME/IP报文的详细介绍(二)

介绍了SOME/IP报文的SD报文(ServiceDiscovery),本片文章开始继续介绍SOME/IP报文。

汽车ECU自动化测试 1113

vc formal实例

gui 方式启动命令,

weixin_45077935的博客 682

堆排序(如何手写堆)

同上面,不过不需要考虑是要往上移(k位置上的数变小了)还是往下移(k位置上的数变大了),down和up只会做一个。####3.删除最小值 heap[1] = heap[size];####4.删除任意一个元素 heap[k] = heap[size];是一个完全二叉树,除了最后一层节点之外,上面都是非空的,最后一层从做到右以此排布。用一维数组存储,下标从1开始,1为根节点,x的左儿子为2x,x的右儿子为2x+1。down(x) 把一个节点往下移 up(x)把一个节点往上移。

2301_80455281的博客 670

Claude code-review 插件深度解析:AI 驱动的智能代码审查系统

Claude Code Review 插件深度解析:AI 驱动的智能代码审查系统 该插件通过多 Agent 并行工作方式自动审查 PR,采用置信度评分机制(80+分保留)过滤误报,确保高质量反馈。核心功能包括: 5个专业化 Agent 并行审查(规范合规性、bug检测、历史分析等) 8步工作流程:从资格检查到 GitHub 评论发布 创新性置信度评分系统(0-100分),严格过滤7类误报 结合 CLAUDE.md 规范和历史 PR 评论实现一致性审查 技术亮点: 多 Agent 架构(Haiku/Sonne

虚心若愚 2264

数据结构与算法 —— 手写排序算法

能手撸堆排序和快速排序,相信你在面试中已经能应付大部分排序问题了。

键盘国治理专家的博客 833

AI大模型开发——transformer模型超全完整版(0基础可懂)

为了更深入的了解transformer模型,我们首先从transformer的诞生聊起吧。transformer在2017年由Vaswani等人首次提出,它摒弃了之前流行的循环神经网络和卷积神经网络的架构,引入了自注意力机制( Self-Attention),显著提高了处理序列数据的能力和效率。transformer模型的这种设计使其在处理长距离依赖问题时, 相比于传统的循环神经网络和长短期记忆网络(LSTM)表现得更加出色,至此, 开启了NLP技术的新篇章。

m0_74922316的博客 2120

Stata极简生存分析

1. 导入数据 webuse drugtr,clear *webuse -- Use dataset from Stata website stset,clear *上一行命令导入进来的数据是“生存时间数据”,会比最原始的数据多四列,这一行命令的目的是重置为原始数据,之所以这样做,是为了显示数据处理的全部过程 codebook drug codebook studytime codebook died codebook age *codebook -- Describe data contents 2.

TOP生物信息 2336

Java手写堆排序(Heap Sort)和案例

建立最大堆之后,最大堆的堆顶元素即为数组中的最大值。我们将堆顶元素与数组中的最后一个元素进行交换。// 交换堆顶和最后一个元素将交换后的堆顶元素(原数组的最后一个元素)下沉到合适的位置,以满足最大堆的性质;每次将当前节点与其子节点进行比较,如果存在比当前节点更大的子节点,则将其与其中较大的子节点进行交换;重复上述比较和交换的步骤,直到当前节点满足最大堆的性质或成为叶子节点。// 维护最大堆性质// 当前节点// 左子节点// 右子节点// 如果左子节点比当前节点大。

qq_22593423的博客 748

哨兵1号回波数据(L0级)提取与SAR成像(全网首发)

本文先展示提取出的回波结果,然后使用RD算法进行成像,展示成像结果,最后附上哨兵1号回波提取的MATLAB代码。

3797

堆排序详解

摘要:堆排序是一种效率非常高的排序算法,同时它的理解以及书写方式都是比较复杂的,以至于很多企业在进行面试的时候都喜欢考察堆排序的书写速度,而堆排序在项目应用中也是有着广泛的天地,因为它的高效率,使得很多数据统计场合都会有堆排序的身影。...

云杉木屋 9165

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

【数据结构】堆排序的实现

堆排序详细解析!你好,欢迎光临媛仔的数据结构进阶之路~

vpurple_的博客 1602

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

详解堆排序

堆排序 1.堆排序基本介绍 (1) 堆排序是利用堆这种数据结构而设计的一种排序算法,堆排序是一种选择排序,它的最坏,最好,平均时间复杂度均为O(nlogn),它也是不稳定排序。 (2) 堆是具有以下性质的完全二叉树:每个结点的值都大于或等于其左右孩子结点的值,称为大顶堆, 注意 : 没有要求结点的左孩子的值和右孩子的值的大小关系。 (3) 每个结点的值都小于或等于其左右孩子结点的值,称为小顶堆 (4) 大顶堆举例说明: 我们对堆中的结点按层进行编号,映射到数组中就是下面这个样子: 大顶堆特点:arr[

xiaoshiguang3的博客 3108

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

排序——堆排序

在复习堆排序之前, 首先我们需要回顾一下什么是堆。堆的本质其实是一个数组。它的物理结构本质上是一个数组。但是它的逻辑结构是一棵完全二叉树。我们在判断一个数组是否是一个堆的时候根据的就是它的逻辑结构。那么怎么根据它的逻辑结构判断是否是一个堆。首先堆的逻辑结构的二叉树的每一个孩子节点都大于它的每一个父亲, 就是堆。这种堆叫做小堆。如果它的逻辑结构的每一个孩子节点都小于它的父亲节点。它同样是个堆, 同时这种堆叫做大堆。

strive_mianyang的博客 1875

堆排序之原地堆排序

之前介绍了堆排序,现在我们来聊聊原地堆排序 【代码】 //原地堆排序 template<typename T> void heapSort3(T arr[], int n) { //将数组构建成一个堆 for(int i = (n - 1) / 2; i >= 0; i--) { __shiftDown(arr, n, i); } for(int i = n - 1; i > 0; i--) { swa

qq_41033011的博客 1848

堆排序算法

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

qq_44111805的博客 7774

《堆排序》堆排序详解

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

Zyy~的博客 5290

堆排序每一趟的结果_堆排序

本文介绍一种神奇的排序方法——堆排序。堆排序不像插入排序和归并排序那样直观,它利用了一种称为堆的数据结构。堆堆本质上是一个数组,但我们将其当做一个近似的完全二叉树来看待。树上的每一个结点对应数组中的一个元素,按层排列。除了最底层外,该树是完全充满的,而且是从左向右填充。下图(a)为我们想象中堆的结构,而(b)则是其实际存储形式。最大堆的特点是,每一个结点都比它的两个孩子结点大(如果孩子结点存在的话...

weixin_36462094的博客 6309

堆排序每一趟的结果_八大排序-堆排序(手写堆排序)

闲聊最近看完一个电视剧,猪脚是胃无限和难忘鸡。比较奇怪的是整个电视剧没有讲爱得死去活来的男女之情反而讲的是男男之间纯纯的知己之情(基情),不过别说还挺好看。有种感觉就像:天下人负你又如何,我定然站你这边...让我想到了当今社会的一些人,这类人习惯权衡利弊后“战队”,或察言观色后随波逐流不顾真理事实。这部剧表达的三观就像一股清流,人生难得一知己,让我内心颇有触动。很喜欢胃无限说的一句话:管他熙熙攘攘...

weixin_39917437的博客 4798

【堆排序回顾】堆排序的理解

文章目录堆排序堆排序有两种方法堆排序第一种实现思路——构造堆+排序:步骤一 :构造初始堆。将给定无序序列构造成一个大顶堆(一般升序采用大顶堆,降序采用小顶堆)。步骤二 :将堆顶元素与末尾元素进行交换,使末尾元素最大。然后继续调整堆,再将堆顶元素与末尾元素交换,得到第二大元素。如此反复进行交换、重建、交换。堆排序过程:代码:为什么说堆排序没有快速排序快?如何理解“堆”?要实现一个堆,先要知道,堆都支持哪些操作以及如何存储一个堆。1、往堆中插入一个元素2.删除堆顶元素 堆排序 堆排序有两种方法 方法一:前提.

NothingYCX的博客 1551

堆排序的原理

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33923762的博客 1735
上一篇: 希尔排序
下一篇: Javascript学习笔记6 DOM扩展
PAT-python-zjw
博客等级 码龄10年 381粉丝 408原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值