【C++】优先级队列和反向迭代器 模拟笔记

news2025/1/18 1:55:17

文章目录

  • 优先级队列
    • 仿函数
    • 适配器模式
    • 堆知识储备
  • 反向迭代器
    • 代码(反向迭代器)
    • 代码(优先级队列)

优先级队列

仿函数

  仿函数,它不是函数(其实是个类),但用法和函数一样。既然是个类,就可以存储很多变量和其它的信息,然后实现纯函数实现不了的功能。所以在一些需要函数作为参数的地方可以用仿函数代替,平常我们经常见到类重载 operator[],而仿函数主要重载 operator(),可以摒弃掉 C 语言那套函数指针用法,减少了指针使用的出错性,同时可以使代码更加美观。

适配器模式

  适配器模式:又叫作变压器模式,它的功能是将一个类的接口变成客户端所期望的另一种接口,从而使原本因接口不匹配而导致无法在一起工作的两个类能够一起工作,属于结构型设计模式
  优先级队列的数据结构本质是堆,而堆逻辑结构是一个二叉树,而存储结构是个数组连续空间。我们可以选择用某种容器来实现它,即用适配器模式,vector 作为缺省值,便能很好满足需求,若我们想用别的容器来实现,也可以手动传参控制。
  有了仿函数和适配器模式,我们就可以控制代码的实现逻辑。我们通过仿函数,控制传参来,实现大小堆,避免把大小堆的代码写死。先看模板参数:

堆知识储备

  向上调整法,传入的参数作为孩子,然后跟双亲比较向上交换(前提是前面的元素构成堆)。向上调整建堆,模仿的是数组元素一个一个尾插的过程,时间复杂度为 O(N*logN)
   向下调整法,传入的参数作为双亲,然后与孩子比较向下交换(前提是下面的元素构成堆)。向下调整建堆,在原有数组的基础上,从倒数第一个非叶子结点,开始向下调整建堆,当双亲逐渐从倒数第一个非叶子结点下标减为 0 时,堆就建好了,时间复杂度为 O(N),时间复杂度小,因为最后一层叶子结点,不需要向下调整

  有了以上知识储备,我们可以轻松实现一个优先级队列,仿函数我们也可以自己调用库里面的 less(大堆), greater(小堆) ,如果对象是自定义类型,我们也可以用库里里面的仿函数解决,因为仿函数可以调用自定义类型的 operator> 等重载,但是如果对象是自定义类型的指针,指针是内置类型,不能重载,我们便只能自己写仿函数 像下面这样:

反向迭代器

  反向迭代器被封装成为一个大类,正向迭代器模板参数都是对象,而它的模板参数是各种容器的正向迭代器。成员变量是正向迭代器,即专门针对正向迭代器实现反向迭代器,因为我们还没有学萃取,所以我们多定两个模板参数 Ref 和 Ptr ,反向迭代器的 ++ 调用正向迭代器的 - -,反向迭代器的 - - 调用正向迭代器的 ++

库里实现

  这里我们看到库里面先 - - 在返回,为什么要这么设计呢?因为正向迭代器和方向迭代器是镜像对称的,就像下面这样。先 - - 在返回刚好弥补了我们对迭代器 rbegin() 的解引用行为,同时保持一致,不让 rend() 进行解引用操作

代码(反向迭代器)

#pragma once

namespace Me
{
	template<class Iterator, class Ref, class Ptr>
	struct ReverseIterator
	{
		typedef ReverseIterator<Iterator, Ref, Ptr> Self;
		Iterator _it;

		ReverseIterator(const Iterator& it)
			:_it(it)
		{}

		Ref operator*()
		{
			Iterator tmp = _it;
			return *(--tmp);
		}

		Ptr operator->()
		{
			return &(operator*());
		}

		Self& operator++()
		{
			--_it;
			return *this;
		}

		Self& operator--()
		{
			++_it;
			return *this;
		}

		bool operator==(const Self& s) const
		{
			return _it == s._it;
		}
		bool operator!=(const Self& s) const
		{
			return _it != s._it;
		}
	};
}

代码(优先级队列)

#pragma once
#include <vector>

namespace Me
{
    //仿函数 Less大堆,Greater小堆
    template<class T>
    struct Less
    {
        bool operator()(const T& t1, const T& t2)
        {
            return t1 < t2;
        }
    };

    template<class T> 
    struct Greater
    {
        bool operator()(const T& t1, const T& t2)
        {
            return t1 > t2;
        }
    };

	template<class T,class container=vector<T>,class compare=Less<T>>
    class priority_queue
    {
    private:
        //向下调整
        void AdjustDown(int parent)
        {
            compare cmp;
            int child = parent * 2 + 1;
            while (child < size())
            {
               // 替代之前的大堆写法:if (child + 1 < _heap.size() && _heap[child + 1] > _heap[child])
                if (child + 1 < _heap.size() && cmp(_heap[child],_heap[child+1]))
                {
                    child++;
                }

                if ( cmp(_heap[parent], _heap[child]) )
                {
                    swap(_heap[parent], _heap[child]);
                    parent = child;
                    child = child * 2 + 1;
                }
                else
                {
                    break;
                }
            }
        }

        //向上调整建堆
        void AdjustUp(int child)
        {
            compare cmp;
            int parent = (child - 1) / 2;
            while (child > 0)
            {
                if ( cmp(_heap[parent],_heap[child]) )
                {
                    swap(_heap[parent], _heap[child]);
                    child = parent;
                    parent = (parent - 1) / 2;
                }
                else
                {
                    break;
                }
            }
        }

    public:
        priority_queue()
        {}

        template <class InputIterator>
        priority_queue(InputIterator first, InputIterator last)
        {
            while (first != last)
            {
                _heap.push_back(*first);
                first++;
            }

            //从倒数第一个非叶子结点向下调整建堆
            for (int i = (_heap.size() - 1 - 1) / 2; i >= 0; i--)
            {
                AdjustDown(i);
            }

        }

        bool empty() const
        {
            return _heap.empty();
        }
        size_t size() const
        {
            return _heap.size();
        }
        const T& top() const
        {
            return _heap[0];
        }
        void push(const T& x)
        {
            _heap.push_back(x);
            AdjustUp(_heap.size() - 1);
        }
        void pop()
        {
            swap(_heap[0], _heap[_heap.size() - 1]);
            _heap.pop_back();
            AdjustDown(0);
        }

    private:
        //成员变量是个vector实现的堆
        container _heap;
    };

}

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

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

相关文章

子类化QThread来实现多线程,moveToThread函数的作用

子类化QThread来实现多线程&#xff0c; QThread只有run函数是在新线程里的&#xff0c;其他所有函数都在QThread生成的线程里。正确启动线程的方法是调用QThread::start()来启动。 一、步骤 子类化 QThread&#xff1b;重写run&#xff0c;将耗时的事件放到此函数执行&#…

轻量级Web报表工具ActiveReportsJS全新发布v4.0,支持集成更多前端框架!

ActiveReportsJS 是一款基于 JavaScript 和 HTML5 的轻量级Web报表工具&#xff0c;采用拖拽式设计模式&#xff0c;不需任何服务器和组件支持&#xff0c;即可在 Mac、Linux 和 Windows 操作系统中&#xff0c;设计多种类型的报表。ActiveReportsJS 同时提供跨平台报表设计、纯…

18.背景轮播

背景轮播 html部分 <div class"container"><div class"slide active" style"background-image: url(./static/20180529205331_yhGyf.jpeg);"></div><div class"slide " style"background-image: url(./s…

vue3+taro+Nutui 开发小程序(二)

上一篇我们初始化了小程序项目&#xff0c;这一篇我们来整理一下框架 首先可以看到我的项目整理框架是这样的&#xff1a; components:这里存放封装的组件 custom-tab-bar:这里存放自己封装的自定义tabbar interface&#xff1a;这里放置了Ts的一些基本泛型&#xff0c;不用…

AtcoderABC238场

A - Exponential or QuadraticA - Exponential or Quadratic 题目大意 给定一个整数 n&#xff0c;判断是否满足 2n >n 2。 思路分析 根据数学知识可知n 的取值在 2 到 4 之间&#xff08;包括 2 和 4&#xff09;&#xff0c;不满足条件 。 时间复杂度 O(1) AC代码 …

MyBatis学习笔记——4

MyBatis学习笔记——4 一、MyBatis的高级映射及延迟加载1.1、多对一1.1.1、第一种方式&#xff1a;级联属性映射1.1.2、第二种方式&#xff1a;association1.1.3、第三种方式&#xff1a;分步查询 1.2、一对多1.2.1、第一种方式&#xff1a;collection1.2.1、第二种方式&#x…

Linux Ubuntu crontab 添加错误 提示:no crontab for root - using an empty one 888

资料 错误提示&#xff1a; no crontab for root - using an empty one 888 原因剖析&#xff1a; 第一次使用crontab -e 命令时会让我们选择编辑器&#xff0c;很多人会不小心选择默认的nano&#xff08;不好用&#xff09;&#xff0c;或则提示no crontab for root - usin…

一文了解Python中的while循环语句

目录 &#x1f969;循环语句是什么 &#x1f969;while循环 &#x1f969;遍历猜数字 &#x1f969;while循环嵌套 &#x1f969;while循环嵌套案例 &#x1f990;博客主页&#xff1a;大虾好吃吗的博客 &#x1f990;专栏地址&#xff1a;Python从入门到精通专栏 循环语句是什…

【N32L40X】学习笔记11-ADC规则通道采集+dma数据传输

ADC规则通道转换 概述 支持 1 个 ADC&#xff0c;支持单端输入和差分输入&#xff0c;最多可测量 16 个外部和 3 个内部源。支持 12 位、10 位、8 位、6 位分辨率。ADC 时钟源分为工作时钟源、采样时钟源和计时时钟源 仅可配置 AHB_CLK 作为工作时钟源。可配置 PLL 作为采样时…

【安全】Sqllabs(1-4) 多种情况浅析

目录 环境⭐ 先要 ⭐⭐⭐⭐⭐ Less - 1 (information_shcema) Less - 2 (假设没有information_schema) Less - 3 (无列名注入) Less - 4 环境⭐ MySQL8.0.12 Nginx1.15.11 先要 ⭐⭐⭐⭐⭐ MySQL5.0以上有这几个数据库mysql, sys&#xff0c;information_schema informa…

前端性能优化——图片优化

一、图片优化措施 优化图片是 Web 前端优化的重要一环&#xff0c;因为图片是 Web 页面中最耗费带宽和加载时间的资源之一。以下是一些通过优化图片来优化 Web 前端的方法&#xff1a; 压缩图片&#xff1a;压缩图片可以减少图片的文件大小&#xff0c;从而减少加载时间。 使…

【数学建模】相关是一个距离指标吗?

一、说明 本文探讨最平凡的数学模型--距离模型。我们知道&#xff0c;任何数学模型如果是个距离模型&#xff0c;那么它是&#xff1a;放心的、自动的、不加任意条件的指标项目。然而另一些度量参数不是距离空间&#xff0c;因此&#xff0c;使用起来必须外加若干条件&#xff…

苹果iOS 16.6 RC发布:或为iPhone X/8系列养老版本

今天苹果向iPhone用户推送了iOS 16.6 RC更新(内部版本号&#xff1a;20G75)&#xff0c;这是时隔两个月的首次更新。 按照惯例RC版基本不会有什么问题&#xff0c;会在最近一段时间内直接变成正式版&#xff0c;向所有用户推送。 需要注意的是&#xff0c;鉴于iOS 17正式版即将…

【CN-Docker】window11下Docker下开启kubernetes

1. 安装Docker 安装docker步骤如下&#xff1a; 下载Docker启用hyper-v 2.1.powershell&#xff0c;管理员运行Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All安装wsl配置Docker镜像加速地址(阿里云) 4.1. "registry-mirrors": [&quo…

Qt/C++音视频开发48-推流到rtsp服务器

一、前言 之前已经打通了rtmp的推流&#xff0c;理论上按照同样的代码&#xff0c;只要将rtmp推流地址换成rtsp推流地址&#xff0c;然后格式将flv换成rtsp就行&#xff0c;无奈直接遇到协议不支持的错误提示&#xff0c;网上说要换成rtp&#xff0c;换了也没用&#xff0c;而…

C++之mutable关键字实例(一百六十五)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

【C++链表】

目录 前言一、搭建链表实现的框架二、链表的构造函数三、链表的尾插四、链表的遍历(重点)迭代器的遍历const修饰的迭代器 五、代码实现 前言 最近用C写了一下list的基本功能&#xff0c;感触颇深。本以为会跟之前用C写list一样会很轻松&#xff0c;没想到更难了。要考虑的东西…

【数据结构】C--单链表(小白入门基础知识)

前段时间写了一篇关于顺序表的博客&#xff0c;http://t.csdn.cn/0gCRp 顺序表在某些时候存在着一些不可避免的缺点: 问题&#xff1a; 1. 中间 / 头部的插入删除&#xff0c;时间复杂度为 O(N) 2. 增容需要申请新空间&#xff0c;拷贝数据&#xff0c;释放旧空间。会有不…

第110天:免杀对抗-GOC#反VT沙盒逆向调试参数加载资源分离混淆加密

知识点 #知识点&#xff1a; 1、C#-混淆&分离&反调试 2、GO-混淆&分离&反调试 3、成品程序-包含反调试VT#章节点&#xff1a; 编译代码面-ShellCode-混淆 编译代码面-编辑执行器-编写 编译代码面-分离加载器-编写 程序文件面-特征码定位-修改 程序文件面-加壳…

Progressive Dual-Branch Network for Low-Light Image Enhancement 论文阅读笔记

这是22年中科院2区期刊的一篇有监督暗图增强的论文 网络结构如下图所示&#xff1a; ARM模块如下图所示&#xff1a; CAB模块如下图所示&#xff1a; LKA模块其实就是放进去了一些大卷积核&#xff1a; AFB模块如下图所示&#xff1a; 这些网络结构没什么特别的&#xf…