【C++ 面试 - STL】每日 3 题(四)

news2024/9/21 16:38:02

✍个人博客:Pandaconda-CSDN博客
📣专栏地址:http://t.csdnimg.cn/fYaBd
📚专栏简介:在这个专栏中,我将会分享 C++ 面试中常见的面试题给大家~
❤️如果有收获的话,欢迎点赞👍收藏📁,您的支持就是我创作的最大动力💪

10. STL 中的 heap 的实现

heap(堆)并不是 STL 的容器组件,是 priority queue(优先队列)的底层实现机制,因为 binary max heap(大根堆)总是最大值位于堆的根部,优先级最高。
binary heap 本质是一种 complete binary tree(完全二叉树),整棵 binary tree 除了最底层的叶节点之外,都是填满的,但是叶节点从左到右不会出现空隙,如下图所示就是一颗完全二叉树:
[图片]

完全二叉树内没有任何节点漏洞,是非常紧凑的,这样的一个好处是可以使用 array 来存储所有的节点,因为当其中某个节点位于i处,其左节点必定位于 2i 处,右节点位于 2i+1 处,父节点位于 i/2(向下取整)处。这种以 array 表示 tree 的方式称为隐式表述法。
因此我们可以使用一个 array 和一组 heap 算法来实现 max heap(每个节点的值大于等于其子节点的值)和 min heap(每个节点的值小于等于其子节点的值)。由于 array 不能动态的改变空间大小,用 vector 代替 array 是一个不错的选择。
那 heap 算法有哪些?常见有的插入、弹出、排序和构造算法,下面一一进行描述。
push_heap 插入算法
由于完全二叉树的性质,新插入的元素一定是位于树的最底层作为叶子节点,并填补由左至右的第一个空格。事实上,在刚执行插入操作时,新元素位于底层 vector 的 end() 处,之后是一个称为 percolate up(上溯)的过程,举个例子如下图:
在这里插入图片描述
新元素 50 在插入堆中后,先放在 vector 的 end() 存着,之后执行上溯过程,调整其根结点的位置,以便满足 max heap 的性质,如果了解大根堆的话,这个原理跟大根堆的调整过程是一样的。
pop_heap 算法
heap 的 pop 操作实际弹出的是根节点吗,但在 heap 内部执行 pop_heap 时,只是将其移动到 vector 的最后位置,然后再为这个被挤走的元素找到一个合适的安放位置,使整颗树满足完全二叉树的条件。这个被挤掉的元素首先会与根结点的两个子节点比较,并与较大的子节点更换位置,如此一直往下,直到这个被挤掉的元素大于左右两个子节点,或者下放到叶节点为止,这个过程称为 percolate down(下溯)。举个例子:
在这里插入图片描述
根节点 68 被 pop 之后,移到了 vector 的最底部,将 24 挤出,24 被迫从根节点开始与其子节点进行比较,直到找到合适的位置安身,需要注意的是 pop 之后元素并没有被移走,如果要将其移走,可以使用 pop_back()。
sort 算法
一言以蔽之,因为 pop_heap 可以将当前 heap 中的最大值置于底层容器 vector 的末尾,heap 范围减 1,那么不断的执行 pop_heap 直到树为空,即可得到一个递增序列。
make_heap 算法
将一段数据转化为 heap,一个一个数据插入,调用上面说的两种 percolate 算法即可。
代码实测:

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;

int main()
{
    vector<int> v = { 0,1,2,3,4,5,6 };
    make_heap(v.begin(), v.end()); //以vector为底层容器
    for (auto i : v)
    {
        cout << i << " "; // 6 4 5 3 1 0 2
    }
    cout << endl;
    v.push_back(7);
    push_heap(v.begin(), v.end());
    for (auto i : v)
    {
        cout << i << " "; // 7 6 5 4 1 0 2 3
    }
    cout << endl;
    pop_heap(v.begin(), v.end());
    cout << v.back() << endl; // 7 
    v.pop_back();
    for (auto i : v)
    {
        cout << i << " "; // 6 4 5 3 1 0 2
    }
    cout << endl;
    sort_heap(v.begin(), v.end());
    for (auto i : v)
    {
        cout << i << " "; // 0 1 2 3 4 5 6
    }
    return 0;
}

11. STL 中的 priority_queue 的实现

priority_queue,优先队列,是一个拥有权值观念的 queue,它跟 queue 一样是顶部入口,底部出口,在插入元素时,元素并非按照插入次序排列,它会自动根据权值(通常是元素的实值)排列,权值最高,排在最前面,如下图所示。
在这里插入图片描述
默认情况下,priority_queue 使用一个 max-heap 完成,底层容器使用的是一般为 vector 为底层容器,堆 heap 为处理规则来管理底层容器实现 。priority_queue 的这种实现机制导致其不被归为容器,而是一种容器配接器。关键的源码如下:

template <class T, class Squence = vector<T>, 
class Compare = less<typename Sequence::value_tyoe> >
class priority_queue{
    ...
protected:
    Sequence c; // 底层容器
    Compare comp; // 元素大小比较标准
public:
    bool empty() const {return c.empty();}
    size_type size() const {return c.size();}
    const_reference top() const {return c.front()}
    void push(const value_type& x)
    {
        c.push_back(x);
        push_heap(c.begin(), c.end(),comp);
    }
    void pop()
    {
        pop_heap(c.begin(), c.end(),comp);
        c.pop_back();
    }
};

priority_queue 的所有元素,进出都有一定的规则,只有 queue 顶端的元素(权值最高者),才有机会被外界取用,它没有遍历功能,也不提供迭代器。
举个例子:

#include <queue>
#include <iostream>
using namespace std;

int main()
{
    int ia[9] = {0,4,1,2,3,6,5,8,7 };
    priority_queue<int> pq(ia, ia + 9);
    cout << pq.size() <<endl;  // 9
    for(int i = 0; i < pq.size(); i++)
    {
        cout << pq.top() << " "; // 8 8 8 8 8 8 8 8 8
    }
    cout << endl;
    while (!pq.empty())
    {
        cout << pq.top() << ' ';// 8 7 6 5 4 3 2 1 0
        pq.pop();
    }
    return 0;
}

12. STL 中 set 的实现?

STL 中的容器可分为序列式容器(sequence)和关联式容器(associative),set 属于关联式容器。
set 的特性是,所有元素都会根据元素的值自动被排序(默认升序),set 元素的键值就是实值,实值就是键值,set 不允许有两个相同的键值。
set 不允许迭代器修改元素的值,其迭代器是一种 constance iterators。
标准的 STL set 以 RB-tree(红黑树)作为底层机制,几乎所有的 set 操作行为都是转调用 RB-tree 的操作行为,这里补充一下红黑树的特性:

  • 每个节点不是红色就是黑色
  • 根结点为黑色
  • 如果节点为红色,其子节点必为黑
  • 任一节点至(NULL)树尾端的任何路径,所含的黑节点数量必相同
    关于红黑树的具体操作过程,比较复杂读者可以翻阅《算法导论》详细了解。
    举个例子:
#include <set>
#include <iostream>
using namespace std;

int main()
{
    int i;
    int ia[5] = { 1,2,3,4,5 };
    set<int> s(ia, ia + 5);
    cout << s.size() << endl; // 5
    cout << s.count(3) << endl; // 1
    cout << s.count(10) << endl; // 0

    s.insert(3); //再插入一个3
    cout << s.size() << endl; // 5
    cout << s.count(3) << endl; // 1

    s.erase(1);
    cout << s.size() << endl; // 4

    set<int>::iterator b = s.begin();
    set<int>::iterator e = s.end();
    for (; b != e; ++b)
        cout << *b << " "; // 2 3 4 5
    cout << endl;

    b = find(s.begin(), s.end(), 5);
    if (b != s.end())
        cout << "5 found" << endl; // 5 found

    b = s.find(2);
    if (b != s.end())
        cout << "2 found" << endl; // 2 found

    b = s.find(1);
    if (b == s.end())
        cout << "1 not found" << endl; // 1 not found
    return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[A-08]ARMv8/ARMv9-Memory-内存空间(动态内存控制器与物理内存设备)

ver0.2 更多精彩内容&#xff0c;请关注微信公众号 # 前言 前序的文章中&#xff0c;已经讲解了ARM架构下管理内存的核心组件MMU的相关背景知识。MMU需要借助页表(Translation Table)衔接起虚拟地址空间和物理内存的空间&#xff0c;实现在一个硬件环境下软件任务的并发执行效…

【不安全的集合类】同步容器(如ConcurrentHashMap)、并发集合(如CopyOnWriteArrayList)

文章目录 一、List的线程不安全二、Set的线程不安全三、Map的线程不安全 日常我们用到的集合的情况会很多&#xff0c;在单线程的情况下&#xff0c;不用考虑到线程安全的问题&#xff0c;但是如果在多线程开发的过程中&#xff0c;我们该选择哪一种类型来保证线程安全性呢 &am…

【网络安全】逻辑漏洞:绕过应用程序重要功能

未经许可,不得转载。 文章目录 正文漏洞影响正文 目标:xxx.com 一个流行的汽车平台,允许用户为经销商留下评论。该平台有一个功能,用户可以点赞评论,并且它限制每个用户对每个评论只能点赞一次。 然而,我找到了绕过的方法(并不是并发)。 在点击“点赞”按钮时拦截请…

Python从0到100(五十七):机器学习-主成分分析机

主成分分析是⼀种常⽤的降维技术&#xff0c;⽤于将⾼维数据集投影到低维空间中&#xff0c;同时保留数据集的主要特征。PCA通过寻找数据中最重要的⽅向&#xff08;主成分&#xff09;&#xff0c;并将数据投影到这些⽅向上来实现降维。 1.基本原理 1、数据中心化&#xff1…

linux-squid代理服务器

squid简介 作为应用层的代理服务软件&#xff0c;Squid 主要提供缓存加速、应用层过滤控制的功能、用来缓冲Internet数据 接受来自人们需要下载的目标&#xff08;object&#xff09;的请求并适当地处理这些请求。也就是说&#xff0c;如果想下载一web页面&#xff0c;他请求…

特殊字符合集(包括各种emoji表情、windows ASCII字符、自定义字母图案等)

██████╗███████╗ ██████╗ ██╔════╝╚══███╔╝██╔═══██╗ ███████╗ ███╔╝ ██║ ██║ ╚════██║ ███╔╝ ██║▄▄ ██║ ███████║███████╗╚██████╔╝ ╚══════╝…

【小呆的热力学笔记】典型热机-燃气轮机的理想热力循环

文章目录 6.1 燃气轮机的理想热力循环6.2 燃气轮机理想热力循环热效率分析6.3 燃气轮机的理想热力循环讨论 6.1 燃气轮机的理想热力循环 燃气轮机装置主要包含三个部件&#xff1a;压气机、燃烧室和涡轮&#xff0c;详见下图示意。其中压气机主要有离心式和轴流式两种&#xf…

视频素材网站无水印的有哪些?热门视频素材网站分享!

今天我们要讨论一个让许多人都感到困扰的问题——那些高质量、无水印的视频素材到底应该在哪里寻找&#xff1f;是不是有时候感觉&#xff0c;找到合适的视频素材比找到理想的伴侣还要困难&#xff1f;不用急&#xff0c;今天我要介绍几个隐藏的宝藏网站&#xff0c;确保你在视…

ARM 异常处理(21)

异常的流程&#xff1a; 首先&#xff1a; 在硬件上阶段&#xff1a; 这里是4大步3小步 然后是 异常处理&#xff1a; 这里主要是保存现场&#xff0c;进行异常处理 然后是 异常返回&#xff1a; 主要指 恢复现场&#xff0c; 再跳转回去。 首先硬件上&#xff…

Scalefit为外骨骼辅助设备提供直观的损伤减轻测量方案

外骨骼辅助设备是有效减轻工厂中工人遭受肌肉骨骼类疾病损伤的有效工具&#xff0c;但想要更加精确直观的看到外骨骼设备能够为工人提供多少精确到数字的帮助&#xff0c;则需要专业的测量工具来实现。 Scalefit人体工程学分析软件 scalefit人体工程学分析软件让作业环境更安全…

北斗GPS车载定位终端,物流货运数智化效率助手

物流行业&#xff0c;作为国民经济的动脉&#xff0c;其效率与成本控制是企业竞争力的关键。随着科技的不断进步&#xff0c;北斗GPS车载定位终端的出现&#xff0c;正成为物流行业数智化转型的加速器&#xff0c;极大地提升了物流货运的效率与安全性。 北斗GPS车载定位终端&a…

计算机毕业设计python停车场车位推荐管理系统y4uzk

目录 博主介绍技术栈&#x1f31f;文末获取源码数据库&#x1f31f;详细视频演示具体实现截图系统设计数据库设计解决的思路python-flask核心代码部分展示可行性论证个人心得操作可行性源码获取 博主介绍 &#x1f447;&#x1f3fb; 博主介绍&#xff1a;&#x1f447;&#…

【软件测试专栏】软件测试 — 用例篇

博客主页&#xff1a;Duck Bro 博客主页系列专栏&#xff1a;软件测试专栏关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ 软件测试 — 用例篇 关键词&#xff1a;测试用例概念、测试用例的…

【基础】Three.js加载纹理贴图、加载外部gltf格式文件

1. 模型使用纹理贴图 const geometry new THREE.BoxGeometry(10, 10, 10);const textureLoader new THREE.TextureLoader(); // 创建纹理贴图加载器const texture textureLoader.load("/crate.gif"); // 加载纹理贴图const material new THREE.MeshLambertMater…

运维问题0001:MM模块-MIGO收货报错“消息号 M7036 对于采购订单********无收货可能”

1、问题解析&#xff1a; 该报错为SAP标准报错类型,针对公司不同配置/业务设计/校验逻辑&#xff0c;导致该问题原因比较多。 常见的问题总结如下&#xff1a; 1&#xff09;输入的PO信息有问题&#xff08;例如&#xff1a;PO输入错误/PO删除状态/PO冻结状态/PO已完成收货等…

HCIE认证要学多久?3个方面决定HCIE学习时长

HCIE认证作为华为公司推出的顶级专业认证&#xff0c;已经成为网络技术领域内的一个标杆。 它不仅象征着专业技能的高峰&#xff0c;也是许多IT专业人士职业发展的重要里程碑。 HCIE作为华为高级认证虽然可以不需要满足任何条件直接报考&#xff0c;但掌握必要的知识内容必不可…

MySQL复习2

高级查询 准备 create database greatselect; use greatselect;drop table if exists class; create table class (cid int(11) not null auto_increment,caption varchar(32) not null,primary key (cid) )engine innoDB AUTO_INCREMENT5 default charset utf8;create tab…

报考条件、材料、流程?关于CISP认证,你必须要了解这些

信息安全一直是一个火热的话题&#xff0c;在近两年又被推上了高峰。对此&#xff0c;相关认证也不例外。 很多朋友都想get一本安全方向的证书&#xff0c;在广大安全方向的认证中&#xff0c;CISP可谓是发展迅猛&#xff0c;并越来越广为人知&#xff0c;也越来越受到IT从业者…

python Bokeh库学习记录

First steps 2: 添加和自定义渲染器 在之前的入门指南中&#xff0c;你使用了Bokeh的figure()函数来绘制折线图。 在本节中&#xff0c;你将使用不同的渲染函数来创建各种其他类型的图表。你还将自定义你的图像外观。 渲染不同的图形符号 Bokeh的绘图界面支持多种不同的图形…

古典显示格式解一偏微分方程并绘制结果的彩色图

解如下偏微分方程 以上公式的Latex代码 \begin{cases}\frac{\partial u}{\partial t}a\frac{\partial ^2u}{\partial x^2}\,\,,0<x<1,t>0\\u\left( x,0 \right) 4x\left( 1-x \right) \,\,,0\leqslant x\leqslant 1\\u\left( 0,t \right) u\left( 1,t \right) 0 ,t\g…