- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我认为这可能是一个微不足道的问题,但过去几天我一直在为此苦苦挣扎。
我有以下 vector :v = [7,3,16,4,2,1]
。我能够在Google简单的minheap算法的帮助下实现,以在每次迭代中获取最小的元素。提取最小元素后,我需要减小某些元素的值,然后将它们冒泡。
我遇到的问题是,我想在常量中以恒定的时间在堆中找到其值必须减小的元素,然后减小该值,然后将其冒泡。
在执行heapify操作之后,heap_vector v_h
看起来像这样:v_h = [1,2,7,4,3,16]
。当我删除min元素1
时,堆 vector 变成[2,3,7,4,16]
。但是在进行交换和冒泡之前,请说我想将7的值更改为4,将16的值更改为4并将将4的值更改为3.5。但是我不确定它们将在堆中的什么位置。相对于原始 vector v
,将给出必须减少的元素的值的索引。我发现我需要有一个辅助数据结构,该结构可以跟踪与元素的原始顺序有关的堆索引(在将所有元素插入minheap之后,堆索引 vector 应看起来像h_iv = [2,4,5,3,1,0]
。每当从minheap中删除一个元素时,heap_index应该为-1。我创建了一个 vector ,试图在有变化时尝试更新堆索引,但是我做不到。
我正在这里粘贴工作,也在https://onlinegdb.com/SJR4LqQO4
我尝试过的一些工作已被注释掉。当冒泡或冒泡操作发生交换时,我无法映射堆索引。我将非常感谢任何能引导我解决问题的人。还请让我知道是否需要重新考虑一些逻辑。
.hpp文件
#ifndef minheap_hpp
#define minheap_hpp
#include <stdio.h>
// #include "helper.h"
#include <vector>
class minheap
{
public:
std::vector<int> vect;
std::vector<int> heap_index;
void bubble_down(int index);
void bubble_up(int index);
void Heapify();
public:
minheap(const std::vector<int>& input_vector);
minheap();
void insert(int value);
int get_min();
void delete_min();
void print_heap_vector();
};
#endif /* minheap_hpp */
#include "minheap.hpp"
minheap::minheap(const std::vector<int>& input_vector) : vect(input_vector)
{
Heapify();
}
void minheap::Heapify()
{
int length = static_cast<int>(vect.size());
// auto start = 0;
// for (auto i = 0; i < vect.size(); i++){
// heap_index.push_back(start);
// start++;
// }
for(int i=length/2-1; i>=0; --i)
{
bubble_down(i);
}
}
void minheap::bubble_down(int index)
{
int length = static_cast<int>(vect.size());
int leftChildIndex = 2*index + 1;
int rightChildIndex = 2*index + 2;
if(leftChildIndex >= length){
return;
}
int minIndex = index;
if(vect[index] > vect[leftChildIndex])
{
minIndex = leftChildIndex;
}
if((rightChildIndex < length) && (vect[minIndex] > vect[rightChildIndex]))
{
minIndex = rightChildIndex;
}
if(minIndex != index)
{
std::swap(vect[index], vect[minIndex]);
// std::cout << "swap " << index << " - " << minIndex << "\n";
// auto a = heap_index[heap_index[index]];
// auto b = heap_index[heap_index[minIndex]];
// heap_index[a] = b;
// heap_index[b] = a;
// print_vector(heap_index);
bubble_down(minIndex);
}
}
void minheap::bubble_up(int index)
{
if(index == 0)
return;
int par_index = (index-1)/2;
if(vect[par_index] > vect[index])
{
std::swap(vect[index], vect[par_index]);
bubble_up(par_index);
}
}
void minheap::insert(int value)
{
int length = static_cast<int>(vect.size());
vect.push_back(value);
bubble_up(length);
}
int minheap::get_min()
{
return vect[0];
}
void minheap::delete_min()
{
int length = static_cast<int>(vect.size());
if(length == 0)
{
return;
}
vect[0] = vect[length-1];
vect.pop_back();
bubble_down(0);
}
void minheap::print_heap_vector(){
// print_vector(vect);
}
#include <iostream>
#include <iostream>
#include "minheap.hpp"
int main(int argc, const char * argv[]) {
std::vector<int> vec {7, 3, 16, 4, 2, 1};
minheap mh(vec);
// mh.print_heap_vector();
for(int i=0; i<3; ++i)
{
auto a = mh.get_min();
mh.delete_min();
// mh.print_heap_vector();
std::cout << a << "\n";
}
// std::cout << "\n";
return 0;
}
最佳答案
“我想将7,4,16到4以及4到3.5的值更改。但是我不确定它们在堆中的位置。必须降低的元素的值的索引将给出原始 vector v。...也请让我知道是否需要重新考虑一些逻辑。”
我建议不要将需要更改的值保留在 vector 内部(可能是v本身),而不是在堆内部操作。堆可以基于作为结构(或类)的元素,这些元素使用值在 vector 中的相应位置保存一个索引,而不是保存(更改)值本身。
该结构(或类)将实现operator <函数,该函数比较从两个 vector 位置中检索到的值以获取相应的索引值。因此,不是将比较值存储在堆元素中并比较a
这样,您需要更新的数值的位置将不会从其原始位置改变。职位信息永远不会过时(据我从您的描述中了解)。
当然,当您对 vector 中的存储值进行更改时,这很容易使堆本身中可能存在的任何顺序无效。据我了解,您的描述在任何情况下都是正确的。因此,根据更改值的方式,可能需要执行新的make_heap以恢复正确的堆顺序。 (尚不清楚,因为这取决于您的预期更改是否违反堆假设,但是除非有其他有力保证,否则假设是安全的。)
我认为其余的内容很简单。您仍然可以按预期操作堆。为简便起见,您甚至可以给struct(或类)一个查找函数,以在 vector 中其对应位置返回当前值,如果您在弹出最小值时需要该值(而不是索引)。
ps这是同一想法的变体。
在上述原始版本中,可能还需要存储指向保存值 vector 的 vector 位置的指针,可能作为该结构(或类)的共享静态指针,以便所有成员都可以取消引用该指针。该 vector 与索引值结合使用,以查找与该元素关联的特定成员。
如果愿意,可以将每个结构(或类)实例直接存储到对应值位置的指针(或迭代器),而不是将共享的 vector 指针和索引存储在每个成员中。如果值是整数,则堆元素结构的成员值可以是int指针。尽管每个指针都可能大于索引值,但这样做的确具有以下优点:它消除了关于保存比较值的数据结构的任何假设,并且与在 vector 中使用索引进行解引用和查找相比,它更简单/更快。 (都是固定时间。)
一个警告:在这种替代方法中,如果要使 vector 的存储位置发生变化,例如,指针值将无效。通过推入新值并以迫使其重新分配其空间的方式扩展它。我假设您只需要更改值,而不用在开始使用堆之后扩展值的数量。但是,如果确实需要这样做,那就是选择索引值的原因之一,因为索引值在扩展 vector 后仍然有效(与指针不同)。
p.p.s.当您要在堆中比较的对象很大时,此技术也很有值(value)。通过仅存储指针(或索引值),堆就不会对大型对象执行许多复制操作,因为它只对指针(或索引值)进行重新排序,因此复制效率更高。实际上,这使您可以在根本不想复制的对象上使用堆。
这是比较函数一个版本的快速构想(现在添加了一些类上下文)。
class YourHeapElementClassName
{
public:
// constructor
explicit YourHeapElementClassName(theTypeOfYourComparableValueOrObject & val)
: m_valPointer(&val)
{
}
bool operator<(const YourHeapElementClassName & other) const
{
return *m_valPointer < *(other.m_valPointer);
}
...
private:
theTypeOfYourComparableValueOrObject * m_valPointer;
}; // YourHeapElementClassName
// and later instead of making a heap of int or double,
// you make a heap of YourHeapElementClassName objects
// that you initialize so each points to a value in v
// by using the constructor above with each v member.
// If you (probably) don't need to change the v values
// through these heap objects, the member value could be
// a pointer to a const value and the constructor could
// have a const reference argument for the original value.
关于c++ - 如何创建辅助数据结构以在minheap中跟踪堆索引以进行C++中的reduce_key操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55313214/
初学者 android 问题。好的,我已经成功写入文件。例如。 //获取文件名 String filename = getResources().getString(R.string.filename
我已经将相同的图像保存到/data/data/mypackage/img/中,现在我想显示这个全屏,我曾尝试使用 ACTION_VIEW 来显示 android 标准程序,但它不是从/data/dat
我正在使用Xcode 9,Swift 4。 我正在尝试使用以下代码从URL在ImageView中显示图像: func getImageFromUrl(sourceUrl: String) -> UII
我的 Ubuntu 安装 genymotion 有问题。主要是我无法调试我的数据库,因为通过 eclipse 中的 DBMS 和 shell 中的 adb 我无法查看/data/文件夹的内容。没有显示
我正在尝试用 PHP 发布一些 JSON 数据。但是出了点问题。 这是我的 html -- {% for x in sets %}
我观察到两种方法的结果不同。为什么是这样?我知道 lm 上发生了什么,但无法弄清楚 tslm 上发生了什么。 > library(forecast) > set.seed(2) > tts lm(t
我不确定为什么会这样!我有一个由 spring data elasticsearch 和 spring data jpa 使用的类,但是当我尝试运行我的应用程序时出现错误。 Error creatin
在 this vega 图表,如果我下载并转换 flare-dependencies.json使用以下 jq 到 csv命令, jq -r '(map(keys) | add | unique) as
我正在提交一个项目,我必须在其中创建一个带有表的 mysql 数据库。一切都在我这边进行,所以我只想检查如何将我所有的压缩文件发送给使用不同计算机的人。基本上,我如何为另一台计算机创建我的数据库文件,
我有一个应用程序可以将文本文件写入内部存储。我想仔细看看我的电脑。 我运行了 Toast.makeText 来显示路径,它说:/数据/数据/我的包 但是当我转到 Android Studio 的 An
我喜欢使用 Genymotion 模拟器以如此出色的速度加载 Android。它有非常好的速度,但仍然有一些不稳定的性能。 如何从 Eclipse 中的文件资源管理器访问 Genymotion 模拟器
我需要更改 Silverlight 中文本框的格式。数据通过 MVVM 绑定(bind)。 例如,有一个 int 属性,我将 1 添加到 setter 中的值并调用 OnPropertyChanged
我想向 Youtube Data API 提出请求,但我不需要访问任何用户信息。我只想浏览公共(public)视频并根据搜索词显示视频。 我可以在未经授权的情况下这样做吗? 最佳答案 YouTube
我已经设置了一个 Twilio 应用程序,我想向人们发送更新,但我不想回复单个文本。我只是想让他们在有问题时打电话。我一切正常,但我想在发送文本时显示传入文本,以确保我不会错过任何问题。我正在使用 p
我有一个带有表单的网站(目前它是纯 HTML,但我们正在切换到 JQuery)。流程是这样的: 接受用户的输入 --- 5 个整数 通过 REST 调用网络服务 在服务器端运行一些计算...并生成一个
假设我们有一个名为 configuration.js 的文件,当我们查看内部时,我们会看到: 'use strict'; var profile = { "project": "%Projec
这部分是对 Previous Question 的扩展我的: 我现在可以从我的 CI Controller 成功返回 JSON 数据,它返回: {"results":[{"id":"1","Sourc
有什么有效的方法可以删除 ios 中 CBL 的所有文档存储?我对此有疑问,或者,如果有人知道如何从本质上使该应用程序像刚刚安装一样,那也会非常有帮助。我们正在努力确保我们的注销实际上将应用程序设置为
我有一个 Rails 应用程序,它与其他 Rails 应用程序通信以进行数据插入。我使用 jQuery $.post 方法进行数据插入。对于插入,我的其他 Rails 应用程序显示 200 OK。但在
我正在为服务于发布请求的 API 调用运行单元测试。我正在传递请求正文,并且必须将响应作为帐户数据返回。但我只收到断言错误 注意:数据是从 Azure 中获取的 spec.js const accou
我是一名优秀的程序员,十分优秀!