小范围排序 --使用堆排序

堆的基本操作及堆排序 Python微信订餐小程序课程视频 https://edu.youkuaiyun.com/course/detail/36074 Python实战量化交易理财系统 https://edu.youkuaiyun.com/course/detail/35475 堆 堆的定义 任意一个子节点总是大于等于或者小于等于父节点的完全二叉树称之为堆,根据字节点和父节点的大小关系,堆又分为大顶堆和小顶堆 大顶堆: 父节点的值总是大于等于子节点的值的堆称之为大顶堆,大顶堆的最大值总是在堆顶 小顶堆: 父节点的值总是小于等于子节点的值的堆称之为小顶 阅读详情

已知一个几乎有序的数组,几乎有序是指,如果把数组排好顺序的话,每个元素移动的距离可以不超过k,并且k相对于数组来说比较小。请选择一个合适的排序算法针对这个数据进行排序。

给定一个int数组A,同时给定A的大小n和题意中的k,请返回排序后的数组。

测试样例:
[2,1,4,3,6,5,8,7,10,9],10,2
返回:[1,2,3,4,5,6,7,8,9,10]

分析:每个元素的距离不超过k,直觉上肯定先想到插入排序,每个元素插入访问不超过k个元素,n个元素时间复杂度为O(N*K)。

更好的办法是堆排序,我们维护一个大小为k的最小堆,先将A[0]~A[k-1]放入堆heap中调整,则heap[0]就是最小值,这个元素就可以被排除出堆,放在A[0]位置。

然后把A[k]加入最小堆,继续调整,最小值放在A[1],然后排除A[1],再加入A[k+1],重复操作,直到最后一个元素。

这时,数组中最后k个元素仍然是没有排序的,这时对他们使用堆排序即可。不过同样是用最小堆的排序,注意--k,因为元素在不断减小。


代码如下:

class ScaleSort {
public:
    vector<int> sortElement(vector<int> A, int n, int k) {
        if(A.size() > 0 && n > 0 && k > 0 && n >= k)
            heap_dispose(A, n, k);
        return A;
    }
private:
    void heap_dispose(vector<int>& A, const int size, int k){ 
        vector<int> heap(k);    //注意预先分配空间,不然会段错误
        std::copy_n(A.begin(), k, heap.begin());
    
        for(int i=(k>>1)-1; i>=0; --i)
            sift_down(heap, i, k); 
    
        for(int i=k; i<size; ++i){  
            A[i-k] = heap[0];   //A[k-k] = A[0]
            heap[0] = A[i];
            sift_down(heap, 0, k); 
        }   
    
        for(int i=size-k; i<size; ++i){  //当k=0是,i=size
            A[i] = heap[0];
            std::swap(heap[0], heap[k-1]);
            sift_down(heap, 0, --k);
        }   
    }   

    int left_child(int i) {
        return i * 2 + 1;
    }   

    void sift_down(vector<int>& heap, int i, const int size){
        int child, temp = heap[i];
        for(child=i; left_child(i)<size; i=child){
            child = left_child(i);
            if(child != size-1 && heap[child] > heap[child+1])
                ++child;
            if(temp > heap[child])
                heap[i] = heap[child];
            else
                break;
        }
        heap[i] = temp;   //注意是i
    }
};

要注意的是,最后是heap[i] = temp,写成heap[child] = temp就等着排错吧。


这里顺便提一下std::copy和std::copy_n函数,它们只负责复制,不会申请空间,提防段错误:

std::copy:

std::copy(start, end, std::back_inserter(container));

std::copy(start, end, container.begin());

std::copy_n:

  OutputIterator copy_n (InputIterator first, Size n, OutputIterator result)


Ubutntu下使用realsense d435i(二):获取某二维像素点的三维坐标 00 准备工作 准备工作包括安装驱动以及pyrealsense2,具体可参考上一篇: Ubutntu下使用realsense d435i(一):准备工作以及安装pyrealsense2 https://blog.youkuaiyun.com/gyxx1998/article/details/121461293 01 通过二维像素点获得物体三维坐标 这个在上一篇已经介绍了代码: realsense d435i获取某像素点三维坐标(计算深度和点云两种方法) https://blog.youkuaiyun.com/gyxx1998/ 阅读详情

相关推荐

【吐血整理-历时两个月,长达万字】FDTD Solutions学习笔记

原教学视频来自于Ansys-Lumerical官方的FDTD100,所看视频来自B站大佬UP主 【Nestor_呐等】 的幸苦翻译,本文内容粘贴自我个人在学习FDTD100时,通过字幕和一些个人理解总结的一份word。整理不易,强烈建议收藏!...

weixin_45719141的博客 10万+

已知一个几乎有序的数组,几乎有序是指,如果把数组排好顺序的话,每个元素移动的距离可以不超过k,并且k相对于数组来说比较小。请选择一个合适的排序算法针对这个数据进行排序。 给定一个int数组A,同时给定

已知一个几乎有序的数组,几乎有序是指,如果把数组排好顺序的话,每个元素移动的距离可以不超过k, 并且k相对于数组来说比较小。请选择一个合适的排序算法针对这个数据进行排序给定一个int数组A, 同时给定A的大小n和题意中的k,请返回排序后的数组。 思路:使用空间复杂度为O(nlogn)中的堆排序,因为快速排序是随机选取一个数然后左右分段,归并排序是分成n 个只有一个元素的序列

sinat_28108651的博客 6861

告别Modern Standby噩梦:Win11睡眠断网冻结的根源剖析与S3睡眠回归实战

本文深入剖析了Windows 11中Modern Standby(现代待机)模式导致睡眠后断网、系统冻结等问题的根源,指出其与硬件驱动、后台活动的兼容性矛盾。文章提供了通过修改注册表键值强制系统回归稳定S3睡眠状态的详细实战步骤,帮助用户彻底解决睡眠故障,实现可靠的远程访问与挂机任务。

weixin_29210727的博客 611

【堆排序】小范围排序算法

堆排序算法使用 最近重新开始研究算法,打算完整的系统性的把算法给过一遍,计划时间三个月,三个月内会不断的更新。 堆排序原理及实现 关于最大堆 什么是最大堆和最小堆?最大(小)堆是指在树中,存在一个结点而且该结点有儿子结点,该结点的data域值都不小于(大于)其儿子结点的data域值,并且它是一个完全二叉树(不是满二叉树)。注意区分选择树,因为选择树(selection tree)概念和最小堆有些类...

志向阿里的猴子的博客 259

Win 11 Fastboot驱动的详细安装教程

Fastboot驱动的详细安装教程

水w的博客 1万+

华为面试手撕真题【判断是ipv4还是ipv6地址】

编写一个函数来验证输入的字符串是否是有效的 IPv4 或 IPv6 地址。

MISAYAONE的博客 1万+

数据结构之常见排序算法的适用范围

1)当数据规模较小时候, 可以使用简单的直接插入排序或者直接选择排序。 (2)当文件的初态已经基本有序, 可以用直接插入排序和冒泡排序。 (3)当数据规模较大时, 应用速度最快的排序算法,可以考虑使用快速排序。当记录随机分布的时候,快 速排序平均时间最短,但是出现最坏的情况,这个时候的时间复杂度是O(n^2),且递归深度为n,所需的占 空间为O(n)。 (4)堆排序不会出现快排那样最坏情况,且堆排...

Java进阶(一刀999) 1870

【Python基础】FastAPI 从入门到项目实战操作详解

【Python基础】FastAPI从入门到使用实战操作详解

congge_study的博客 456

OP-TEE虚拟化支持详解

OP-TEE虚拟化支持解析 OP-TEE提供实验性虚拟化方案,支持多虚拟机共享安全执行环境。核心特性包括: 配置选项:CFG_VIRTUALIZATION启用虚拟化,CFG_VIRT_GUEST_COUNT限制虚拟机数量并分配均等内存资源; Hypervisor协作:需实现虚拟机生命周期通知、SMC参数转换、内存固定等关键协议; 当前限制:仅支持Armv8架构,硬件资源共享有限,采用静态内存配额机制; 架构实现:通过MMU分区切换和扩展内存分配器实现多租户隔离,Nexus核心层管理虚拟机上下文。该方案适用于

Linux内核架构师 109

Agentic AI应用架构师如何提升AI应用的灵活性

可扩展性(Scalability):快速添加新功能或扩展任务范围(如Agent从“客服”扩展到“供应链管理”);可修改性(Modifiability):调整Agent的决策逻辑或动作策略,无需重构整个系统;鲁棒性(Robustness):在环境异常或数据噪声下保持性能稳定;自适应(Self-Adaptation):自主学习新场景,无需人工干预。状态空间(S):Agent能感知的所有内部/外部状态(如用户需求、环境数据);动作空间(A):Agent能执行的所有动作(如调用工具、发送消息);

项目管理的博客 598

使用堆排序解决的题目

已知一个几乎有序的数组,几乎有序是指,如果把数组排好顺序的话,每个元素移动的距离可以不超过k, 并且k相对于数组来说比较小。请选择一个合适的排序算法针对这个数据进行排序给定一个int数组A, 同时给定A的大小n和题意中的k,请返回排序后的数组。 思路:使用空间复杂度为O(nlogn)中的堆排序,因为快速排序是随机选取一个数然后左右分段,归并排序是分成n 个只有一个元素的序列,他们与序列顺序

qq_36008665的博客 1059

2025爬虫实战:某音直播间实时弹幕获取原理及源码分析

某音直播弹幕虽然没有直接挂在 DOM 上,但由于用的是西瓜播放器,弹幕是通过 JS 接口动态渲染的,这就给了我们 Hook 的机会。关键点是找到调用的位置,然后拦截并输出对象里的message字段。这个思路其实也适用于其他前端渲染的播放器,比如 B 站的 DPlayer、HLS.js、甚至很多自研播放器都有类似结构。

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 1820

堆排序

堆排序 如何手写一个堆? Method 1、插入一个数 2、求集合当中的最小值 3、删除最小值 4、删除任意一个元素 5、修改任意一个元素 堆是一棵完全二叉树:除了最后一层节点,以上层都是依次排布的。 Example 输入一个长度为n的整数数列,从小到大输出前m小的数。 输入格式 第一行包含整数n和m。 第二行包含n个整数,表示整数数列。 输出格式 共一行,包...

ai_XZP_master 275

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

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

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

C/C++ 堆排序的非递归实现

C/C++ 数据结构堆排序的快速实现本章所需知识点:大根堆和小根堆的定义如何编写非递归的堆排序 本章所需知识点: 1.父结点索引:(i-1)/2(这里计算机中的除以2,省略掉小数) 2.左孩子索引:2*i+1 3.右孩子索引:2*i+2 大根堆和小根堆的定义 大根堆和小根堆 性质:每个结点的值都大于其左孩子和右孩子结点的值,称之为大根堆;每个结点的值都小于其左孩子和右孩子结点的值,称之为小根堆。 如何编写非递归的堆排序 堆排序原理参考文档 非递归堆排序流程图: 求最大根堆即是数组A的MAXSIZE-1数

高冷的上官梓芸的博客 1429

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

堆排序实战-利用堆排序解决一个排序问题(java实现)

一个数组是无序的,但内部有自己的规律,每个元素需要调整的距离不超过k的长度。现在需要利用堆排序来将数组调成有序的状态。2.由于每个元素调整长度不超过k,我们此时把堆顶元素弹出,就是最小值,3.然后依次加进去一个元素,弹出堆顶,就可以实现排序了。2.写一个系统实现的排序,方便校验上面堆排序的方法。5.最后把用到的一些工具方法也提供下,让你开箱即用。1.我们可以利用小根堆,加进去k长度的元素。1.先生成一个满足要求的数组。3.比较两个数组是否相等。

SP_1024的博客 90

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

【算法学习】排序算法-堆排序

思想: 对全部元素n-1建立大顶堆后,将顶与最后一个元素交换; 而后对n-2个元素建堆,将顶与倒数第二个元素交换; 直到最后两个元素建堆。 C代码 #include "stdio.h" void array_printf(int a[],int n); void sort_heap(int a[],int n); void build_heap(int a[],int e); int m

附子 530

在线编程--小范围排序

小范围排序是指一个几乎有序的数组,个别元素需要进行调整,但调整的幅度不超过k,k相对于整个数组很小。 思想:可以使用插入排序,时间复杂度不超过O(N*k) 最好方法是使用堆排序,建立一个k大小的堆,对数组依次进行排序。题目: 已知一个几乎有序的数组,几乎有序是指,如果把数组排好顺序的话,每个元素移动的距离可以不超过k,并且k相对于数组来说比较小。请选择一个合适的排序算法针对这个数据进行排序。

上善若水,厚德载物 619

堆排序c++实现

堆排序c++实现 #include<iostream> #include<vector> using namespace std; void heapify(vector<int>&vec,int n,int index) { if(index >= n) { return; } int leftIndex = 2*index + 1; int rightIndex = 2*index + 2; ...

qq_27654007的博客 188

算法实现-计数排序(使用堆排序筛选数组中的最大值)

  使用堆排序选出数组中的最大值,然后使用计数排序对整个数组进行排序   package com.sort;   public class HeapSort { /** * 将整棵树构建为最大堆 * @param a */ public void builMaxHeap(int[] a){ int length = a.length-1;//堆排序数据长度...

lyliuyangyang的博客 354

Serverless Framework plugin install 命令完全指南:安装插件并自动写入 plugins 配置

`serverless plugin install` 是 Serverless Framework 中用于为当前服务安装第三方插件的核心命令,它不仅负责将插件下载到项目依赖中,还会自动把插件名追加到服务配置文件(`serverless.yml` / `serverless.json`)的 `plugins` 列表里,省去手动编辑配置文件的步骤。本文以 AWS Provider 命令行参考文档为主

gitblog_00227的博客 504

NOJ1066堆排序

堆排序 时间限制(普通/Java):1000MS/3000MS          运行内存限制:65536KByte 总提交:244            测试通过:153 描述 给定输入排序元素数目n和相应的n个元素,写出程序,利用内排序算法中堆排序算法进行排序,并输出排序最后结果的相应序列。 输入 共两行,第一行给出排序元素数目n,第二行给出n个元素,1≤n≤100000,每个

我的博客 634

PTA 堆排序 函数题 c++

其中anm都是用户传入的参数。n是数据元素个数;m是统计个数。

m0_74374629的博客 756

排序算法---堆排序

排序算法---堆排序

zyp_zl的博客 802

堆排序--优先级队列例题

已知一个几乎有序的数组,几乎有序是指,如果把数组排好序的话,每个元素移动的距离不超过K,并且k相对于数组来说比较小。请选择一个合适排序算法针对这个数据进行排序。

niceYF的博客 449

手写堆 (排序)

然而,down ()和up()

2301_80962683的博客 405
上一篇: muduo库的EventLoopThread类剖析
下一篇: 最短排序子数组
FreeeLinux
博客等级 码龄11年 421粉丝 356原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值