从 std::heap 中间删除一个元素

2024-04-22

我使用优先级队列作为调度程序,但有一个额外的要求。我需要能够取消预定的项目。这相当于从优先级队列中间删除一个项目。

我不能使用std::priority_queue因为对除顶部之外的任何元素的访问都受到保护。

我正在尝试使用algorithm的堆函数。但我仍然缺少我需要的那部分。当我从堆中间删除一个元素时,我希望它能够有效地重建自身。 C++ 提供了这些堆函数:

  • std::make_heap O(3n)
  • std::push_heap O(lg(n))
  • std::pop_heap O(2lg(n))

我想要一个新功能,例如std::repair_heap带有一个大O 3n。我会向它提供被取消的项目曾经驻留的孔的位置,并且它会正确调整堆。

不提供一个似乎是一个巨大的疏忽std::repair_heap功能。我错过了一些明显的东西吗?

是否有提供符合 stl 的库std::repair_heap?

是否有更好的数据结构来建模调度程序?

NOTE:
我没有使用std::map出于几个原因。

  • 堆具有恒定的内存开销。
  • 堆具有很棒的缓存局部性。

我猜您知道要删除堆容器(索引 n)中的哪个元素。

  1. 设置值v[n] = BIG;价值BIG确实比堆中的任何其他值都大。
  2. Call std::push_heap( v.begin(), v.begin()+n+1 );
  3. Call std::pop_heap( v.begin(), v.end() );
  4. Call v.pop_back();
  5. Done

运算复杂度为 O(ln(n))

RE: 要求提供证明

首先,预选赛: 此方法假设了有关 std push_heap 使用的算法的一些信息。
具体来说,它假设 std push_heap( v.begin(), v.begin()+n+1 ) 只会改变范围 [0, n]
对于那些作为 n 的上升元素的元素,即以下集合中的索引:

A(n)={n,(n-1)/2,((n-1)/2-1)/2....0}.  

以下是 std Push_heap 的典型规范:

http://www.cplusplus.com/reference/algorithm/push_heap/ http://www.cplusplus.com/reference/algorithm/push_heap/“给定一个堆范围 [first,last-1),此函数通过将 (last-1) 中的值放入其相应位置,将堆范围扩展到 [first,last)。”

它保证使用您在教科书中读到的“正常堆算法”吗? 你告诉我。

无论如何,这是您可以运行并根据经验查看它是否有效的代码。 我用的是VC 2005。

#include <algorithm>
#include <vector>
#include <iostream>

bool is_heap_valid(const std::vector<int> &vin)
{
    std::vector<int> v = vin;
    std::make_heap(v.begin(), v.end());
    return std::equal(vin.begin(), vin.end(), v.begin());
}


int _tmain(int argc, _TCHAR* argv[])
{
    srand(0);
    std::vector<int> v;
    for (int i=0; i<100; i++)
    {
        v.push_back( rand() % 0x7fff );
    }
    std::make_heap(v.begin(), v.end());

    bool bfail = false;
    while( v.size() >= 2)
    {
        int n = v.size()/2;
        v[n] = 0x7fffffff;
        std::push_heap(v.begin(), v.begin()+n+1);
        std::pop_heap(v.begin(), v.end());
        v.resize(v.size()-1);
        if (!is_heap_valid(v))
        {
            std::cout << "heap is not valid" << std::endl;
            bfail = true;
            break;
        }
    }
    if (!bfail)
        std::cout << "success" << std::endl;

    return 0;

}

但我还有另一个问题,那就是如何知道需要删除的索引“n”。我看不到如何在使用 std push_heap 和 std pop_heap 时跟踪它(知道堆中的位置)。我认为你需要编写自己的堆代码,并在每次在堆中移动对象时将堆中的索引写入到该对象中。叹。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从 std::heap 中间删除一个元素 的相关文章

随机推荐

  • 非常慢:ActiveRecord::QueryCache#call

    我在 Heroku 上有一个应用程序 在 Puma 上运行 workers 2 threads count 3 pool 5 看起来有些请求被困在中间件中 这使得应用程序非常慢 非常 我看到其他人讨论过这个问题 但到目前为止还没有解决方案
  • digest_path 和 asset_digest_path 不允许摘要 URL

    我在制作资产方面经历了一段相当艰难的时期 归根结底 我试图重写 sprokets 辅助模块来尝试看看发生了什么 当我将其重写为以下内容时 module Sprockets module Rails module Helper def com
  • 使用 JavaScript 正则表达式进行全局匹配

    通常当你做类似的事情时 test match e 你会收到一个数组 e e 其中第一个元素是匹配本身 第二个元素是选择器 大括号 但是当使用全局修饰符时 如 test match e g 它会忽略匹配 但如果我根本不使用选择器则不会 我想知
  • Grafana:用于访问时间范围的[from,to]值的全局变量

    我正在使用 MySQL 数据源进行一些测试并利用时间过滤器 http docs grafana org reference templating the timefilter or timefilter variable在 SQL 查询中
  • 只读属性总是“原子的”吗?

    有时我们有一个简单的只读属性 其值可能会改变 property readonly NSFetchedResultsController FetchController property readonly NSFetchRequest Fet
  • 将子 DIV 移到父 DIV 之外

    我就直接进入正题吧 我有一个宽度为 100 的子 div 它位于具有固定宽度的包装器下 我想知道如何使子 div 突破 并具有 100 全屏页面宽度 代码是这样的 我尝试使用相对 绝对定位 但没有运气 div class wrapper S
  • (二进制、NDK)C 应用程序与 Java 应用程序的反编译(Dalvik 字节码)

    Well 由于我对重新设计很感兴趣 到目前为止我在 Android 重新设计上花费了大量时间 尽管如此 我还是遇到了编译二进制 C 代码 NDK 的问题 并且我知道将其反编译回 C C 比将 DEX 文件反编译回或多或少要困难得多 以及Ja
  • 检查数据库是否存在并且当前登录可以访问

    我知道我可以使用 检查数据库是否存在 SELECT FROM sys databases WHERE name database name or SELECT DB ID database name 无论当前登录是否有权访问 都可以执行此检
  • 将 Microsoft.SqlServer.Types 与 Dapper 一起使用时出现 RuntimeBinderInternalCompilerException

    使用目标平台设置为以下之一的 Sql Server Data Tools 项目 SQL Server 2008 SQL Server 2012 SQL Server 2014 并部署到 localdb Projects 或 localdb
  • 如何使用 JSHint 禁用有关“this”和严格模式的警告?

    我正在使用 AngularJS v1 5 编写一个 Web 应用程序 因此我有一些控制器 在这些控制器中我经常声明如下内容 function myController someDirectives var ctrl this My code
  • 如果第一个域有文件夹路径,如何将一个域 301 重定向到另一个域

    我想要从 www olddomain com 进行 301 重定向到 newdomain com 的根目录 但无论旧域上的文件夹路径是什么 我都希望它能够正常工作 例如 以下内容都应重定向到 newdomain com 的根目录 www o
  • iPhone。粒子系统性能

    我试着把雨和雪画成粒子系统 using 核心显卡 在模拟器中渲染进行得很好 但是当我在真实设备上运行我的应用程序时渲染速度变慢 所以 请告诉我增加方法iPhone 上的粒子系统绘图性能 也许我应该使用OpenGL为此或核心动画 OpenGL
  • 如何将复选框绑定到值的倒数?

    我有一个情况 当我需要将一个复选框和另一个 DOM 元素的可见性绑定到我的 viewModel 的布尔属性的逆时
  • 使用 Google Cloud Functions 实现微服务的 API 网关

    Inputs 例如 我们有一些服务 账户服务 产品服务 支付服务 每项服务都是一个单独的 Google Cloud Function 每个服务都有自己的 HTTP API 例如 账户服务有 https REGION FUNCTIONS PR
  • 完全丢失:Django Rest Framework 中的序列化器和更新的多对多

    我已经研究这个问题几个小时了 但没有找到解决方案 我只是不明白 我有一个有很多孩子的父母 我创建了一个视图 允许我获取父级的所有子级 现在我想结束该列表 并使用新的子列表对父列表进行 PATCH 我明白我需要写一个自定义update方法 但
  • 如何在Python中按扩展名删除文件?

    我只是想制作一个通过 zip 扩展名删除项目的脚本 import sys import os from os import listdir test os listdir Users ben downloads for item in te
  • 检测跨域弹窗何时关闭

    我有一个 JavaScript 应用程序 位于domainA com 上 为了验证用户身份并设置 cookie 它会在 domainB com 上打开一个弹出窗口 这类似于 Twitter 的 anywhere 如何检测domainB co
  • 如何在 R 中绘制更平滑的曲线

    Using R 我画了一个阴影图 如果您看到曲线 它们并不平滑 如何让它们变得光滑 即使是 Excel 也能绘制出更加平滑的曲线 设备功能 Windows 7 屏幕分辨率 1366 x 768 最大 这是情节 以下代码用于绘制绘图 plot
  • 删除前 n 个单词并计数

    我有一个数据框对于文本列 我需要忽略或消除前 2 个单词并计算该列中的字符串数量 b lt data frame text c hello sunitha what can I do for you hi john what can I d
  • 从 std::heap 中间删除一个元素

    我使用优先级队列作为调度程序 但有一个额外的要求 我需要能够取消预定的项目 这相当于从优先级队列中间删除一个项目 我不能使用std priority queue因为对除顶部之外的任何元素的访问都受到保护 我正在尝试使用algorithm的堆