【C++面试刷题】快排(quick_sort)和堆排(priority_queue)的细节问题

一、快排的快速选择算法两种思路(面试会考)O(N)

快排的三数取中思路:
重要的是将它三个数进行排序最左为最小,中间为次小,最右为最大的数。(错误原因:我刚开始没有将这三个数进行排序,只是找出其最中间的值,导致时间超时了,这是因为
1、避免最坏情况:如果数组已经部分排序或完全排序,直接选择第一个数或最后一个数作为枢轴值可能会导致分割极不平衡,即一个子数组包含大部分元素,而另一个子数组只包含少数元素。这种情况会使快速排序的性能退化到O(n^2)。通过三数取中法,我们可以选择一个更居中的数作为枢轴值,从而在一定程度上避免这种不平衡的分割。
2、提高分割效率:当选择的枢轴值比较居中时,数组被分割成两个大小相近的子数组,这使得后续的递归排序过程更加高效。因为每次递归调用都需要对两个子数组进行排序,如果子数组的大小相近,则递归的深度会更小,从而减少了排序所需的总时间。
3、减少比较次数:虽然三数取中法本身需要一些额外的比较操作来确定中间数,但这些比较操作的开销相对于整个排序过程来说是微不足道的。而且,通过选择一个更好的枢轴值,我们可以减少后续分割和递归过程中的比较次数,从而提高整体排序效率。)
在这里插入图片描述
快排的随机值思想:
仅仅是随机,是概率求期望,因为是对于随机序列,存在一种称为“Linear Time Median Finding”的算法,该算法能够在最坏情况下也达到O(n)的时间复杂度。
在这里插入图片描述

二、TopK问题–用堆求前K个大/小or第K大/小的元素O(N*logK)

1、开胃小菜

思考一下,既然前K个大/小的元素,那么其实就可以用优先级队列来解决这个问题,可是,我们要注意的是面试中大概率不会说你是否会用这个优先级队列(对于一个C++程序员这个应该是基操吧!?),而大概率是考一下topk问题的这个堆是怎么整出来的,其实也就是我们数据结构中的堆(二叉树)这个部分的向上调整和向下调整建堆的过程,我们先来看一下下面这道题的具体做法(堆和快排),再来讲解一下建堆的具体过程用以我们暂时的理解应对面试。
这是题目:
在这里插入图片描述
这是答案:
在这里插入图片描述
这是解析:
我们简单思考一下这里其实我们建立的是一个小根堆,因为有个greater<int>,所以是小根堆,这里为什么要建立小根堆是因为,当我们新插入的元素比堆顶元素大的时候,那么就交换与堆顶元素,再向下调整就ok了,那么也就是每次插入的时候替换掉最小的元素呗!
而如果是 对于找前K小的元素的时候,那么就建立个大根堆即可,因为我堆顶的元素是最大的,那么当比堆顶的数小的数进来的时候就替换掉并向下调整呗!

这是快排部分:
在这里插入图片描述
这是快排部分解析:
假设我们建立的是升序,那么我们只需要判断第k大的元素是否在最右区间,也就是数量可以比较一下,不在的话就判断是否在等于区间,不在的话就判断是否在最左区间,这里的细节就是在最左区间的时候传进去的大小只有k-b-c这是因为剩下两个区间都已经判断过确实没有,到最左区间就是减去前两个区间的数量的个数。

2、正式说明堆排序的问题

要想弄清楚堆排序,那么就必须先了解建堆的过程,也就是向上调整算法和向下调整算法。

up就是孩子比父亲大就交换,迭代上去,再判断孩子比父亲大就交换。

typedef int HPDataType;
void Swap(HPDataType* p1, HPDataType* p2) 
{ 
	HPDataType temp = *p1; 
	*p1 = *p2; 	
	*p2 = temp; 
}
//向上调整(除了child,其余全是堆)
//时间复杂度:O(N*logN)
void AdjustUp(HPDataType* a, HPDataType child)
{
    //判断孩子和父母的关系
    int parent = (child - 1) / 2;
    while (child > 0)
    {
        if (a[child] > a[parent])
        {
            Swap(&a[child], &a[parent]);
            //迭代
            child = parent;
            parent = (child - 1) / 2;
        }
        else
        {
            break;
        }
    }
}

down就是因为我们前面是把大根堆的堆顶结点和新进入的值比较小的节点交换了,所以需要向下调整一下,依旧保持此时除了最后一个最大的元素以外的第二大元素当大头,只需要与孩子节点一直比较就ok了,直到孩子节点到最后一个节点了。

//向下调整
//时间复杂度:O(N)
void AdjustDown(HPDataType* a, HPDataType n, HPDataType parent)
{
    int child = parent * 2 + 1;
    while (child < n)
    {
        if (child + 1 < n && a[child + 1] > a[child])
        {
            ++child;
        }
        if (a[child] > a[parent])
        {
            Swap(&a[child], &a[parent]);
            parent = child;
            child = parent * 2 + 1;
        }
        else
        {
            break;
        }
    }
}
void HeapSort(int* a, int n)
{
    //插入建堆
    //建堆 -- 向上调整
    //时间复杂度为O(N*logN)
    //升序 -- 建大堆
    int i = 1;
    for (i = 1; i < n; i++)
    {
        AdjustUp(a, i);
    }
    //从后往前调整
    int end = n - 1;
    while (end > 0)
    {
        Swap(&a[0], &a[end]);
        AdjustDown(a, end, 0);
        --end;
    }
}

上述是一个升序的数组了,其实也就是先建立大根堆,每次把最大的哪个先选出来放到最后就好了!

结论:
在这里插入图片描述

3、附录

具体详看:
堆排序和TOP-K问题
堆(二叉树)的顺序实现

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/900305.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Notepad++通过自定义语言实现日志按照不同级别高亮

借助Notepad的自定义语言可以实现日志的按照不同级别的高亮&#xff1b; 参考&#xff1a; https://blog.csdn.net/commshare/article/details/131208656 在此基础上做了一点修改效果如下&#xff1a; xml文件&#xff1a; <NotepadPlus><UserLang name"Ansibl…

洞察数据之美:用可视化探索销售与温度的关系

目录 数据可视化1.气温数据可视化图片展示将最高和最低气温合并绘制折线图&#xff1a;将最高和最低气温合并绘制散点图&#xff1a; 2.销售数据可视化几种常见的销售数据可视化方法及其适用场景&#xff1a;图片展示通过热力图和堆叠柱状图的直观展示&#xff0c;可以得出以下…

CAS简介

#1024程序员节&#xff5c;征文# CAS是什么&#xff1f; CAS&#xff08;Compare And Swap&#xff09;&#xff0c;即比较与交换&#xff0c;是一种乐观锁的实现方式&#xff0c;用于在不使用锁的情况下实现多线程之间的变量同步。 CAS操作包含三个操作数&#xff1a;内存位…

【Nginx】win10 安装Nginx

1.下载 nginx: download 2.安装 解压即可 3.启动 可以自己修改端口&#xff0c;conf/nginx.conf 确保端口不被占用cmd启动&#xff08;不要双击nginx.exe启动&#xff0c;至于原因我粘贴一下&#xff09; start nginx.exe 可以看到是后台运行&#xff0c;还不错 访问&…

易基因:Nat Commun:ATAC-seq等揭示恒河猴大脑高分辨率解剖区域的转录组和开放染色质图谱

大家好&#xff0c;这里是专注表观组学十余年&#xff0c;领跑多组学科研服务的易基因。 恒河猴是神经科学研究中常用的模型动物&#xff0c;其大脑结构和功能与人类大脑相似。大脑中复杂的遗传网络是灵长类动物行为、认知和情感的基础&#xff0c;一直是神经科学的核心。大脑…

全面了解MindSporeLite轻量化推理工具(概念版)

一、参考资料 技术干货&#xff5c;极速、极智、极简的昇思MindSpore Lite&#xff1a;助力华为Watch更加智能 二、相关概念 MCU MCU的全称是Microcontroller Unit&#xff0c;中文可以称为微控制器或者单片机。MCU既可用于汽车电子、工业控制等领域&#xff0c;也可应用于…

Docker入门之构建

Docker构建概述 Docker Build 实现了客户端-服务器架构&#xff0c;其中&#xff1a; 客户端&#xff1a;Buildx 是用于运行和管理构建的客户端和用户界面。服务器&#xff1a;BuildKit 是处理构建执行的服务器或构建器。 当您调用构建时&#xff0c;Buildx 客户端会向 Bui…

【纯血鸿蒙】安装hdc工具

这里我先写Mac版的,Windows的在下面 首先要知道你的SDK安装在哪里了,不知道的话,可以打开DevEco Studio,打开设置页面里的HarmonyOS SDK,这个我们之前配置环境变量的时候用过。 其实主要是用到这里toolchains下的hdc命令。 所以我们需要配置环境变量。 1、打开Mac下的…

RabbitMQ是一个开源的消息代理和队列服务器

RabbitMQ是一个开源的消息代理和队列服务器&#xff0c;它基于AMQP&#xff08;Advanced Message Queuing Protocol&#xff0c;高级消息队列协议&#xff09;协议实现&#xff0c;同时也支持其他消息协议如STOMP、MQTT等。作为一个可靠的消息传递服务&#xff0c;RabbitMQ在分…

Nginx+Tomcat 动静分离

1. NginxTomcat 环境 Nginx 处理静态资源的优势同样可以应用在 Tomcat 环境中 。从实现方法上来说&#xff0c;NginxTomcat 环境的搭建思路与前面完成的 NginxApache 环境是完全相同的&#xff0c;只需要将 Nginx 与 Tomcat 的站点文档目录配置到同一目录下&#xff0c;利用 N…

Python 打包成 EXE 的方法详解

#1024程序员节&#xff5c;征文# 日常开发中&#xff0c;python由于其便捷性成为了很多人的首选语言&#xff0c;但是python的环境配置也是有点麻烦的&#xff0c;那么我们如何让其变得更加友好呢&#xff1f;没错&#xff0c;就是打包成exe可执行文件。 一、PyInstaller 简介…

在使用 RabbitMQ 作为消息代理时,多个 Celery 实例(或应用)可以共享同一个 RabbitMQ 实例

在使用 RabbitMQ 作为消息代理时&#xff0c;多个 Celery 实例&#xff08;或应用&#xff09;可以共享同一个 RabbitMQ 实例。这样做可以简化基础设施管理&#xff0c;同时允许不同的 Celery 应用之间进行消息传递和协作。下面是如何配置多个 Celery 实例以使用同一个 RabbitM…

鸿蒙到底是不是纯血?到底能不能走向世界?

关注卢松松&#xff0c;会经常给你分享一些我的经验和观点。 2016年5月鸿蒙系统开始立项。 2018年美国开始经济战争&#xff0c;其中一项就是制裁华为&#xff0c;不让华为用安卓。 2019年8月9日华为正式发布鸿蒙系统。问题就出在这里&#xff0c;大家可以仔细看。 安卓一…

Java之bean操作【复制】

#1024程序员节 | 征文# 文章目录 一、深拷贝二、不为空拷贝三、List转换 1024 祝各位大佬 节日快乐&#xff01; 在Java项目开发中&#xff0c;对Java对象操作如bean复制等&#xff0c;可使用 一、深拷贝 private static final Map<String, BeanCopier> BEAN_COPIER_M…

【忍无可忍,无需再忍】永久解决xshell or xftp 更新问题

1 背景介绍 提示“要继续使用此程序,您必须应用最新的更新或使用新版本”&#xff0c;笔者版本是xshell 6 距离一段时间不使用&#xff0c;或者遇到更新场景&#xff0c;总是会弹出这个框&#xff0c;实在是忍无可忍&#xff0c;无需再忍。 2 思路介绍 笔者上一篇关于如何解…

No.21 笔记 | WEB安全 - 任意文件绕过详解 part 3

&#xff08;一&#xff09;空格绕过 原理 Windows系统将文件名中的空格视为空&#xff0c;但程序检测代码无法自动删除空格&#xff0c;使攻击者可借此绕过黑名单限制。基于黑名单验证的代码分析 代码未对上传文件的文件名进行去空格处理&#xff0c;存在安全隐患。相关代码逻…

24.redis高性能

Redis的单线程和高性能 Redis是单线程吗&#xff1f; Redis 的单线程主要是指 Redis 的网络 IO 和键值对读写是由一个线程来完成的&#xff0c;这也是 Redis 对外 提供键值存储服务的主要流程。 Redis 的多线程部分&#xff0c;比如持久化、异步删除、集群数据同步等&#xff…

C# 委托简述

1.委托 1.1什么是委托 委托委托 官网解释: 委托是安全封装方法的类型&#xff0c;类似于 C 和 C 中的函数指针。 与 C 函数指针不同的是&#xff0c;委托是面向对象的、类型安全的和可靠的。 委托的类型由委托的名称确定。 个人理解:委托就是一个方法的模板。它可以接收…

关于bp抓不到本地包

关于bp抓不到本地包 关于bp抓不到本地包 关于bp抓不到本地包 pikachu练习时&#xff0c;发现用bp抓本地&#xff08;127.0.0.1&#xff09;数据包时&#xff0c;竟然直接放行访问。 是因为系统默认127.0.0.1无法使用代理&#xff0c;因此bp才抓不到本地数据包&#xff0c;需要…

Python入门:Python如何强制终止程序(如何强制终止多线程程序)

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 文章内容 📒📝 优雅的退出📝 强制的终止📝 应用场景对比🚀 优雅的退出🚀 强制的终止⚓️ 相关链接 ⚓️📖 介绍 📖 在开发过程中,有时候需要在满足一些条件的情况下让程序强制终止运行?今天我们将了解一下 Py…