具有堆和映射同等能力的数据结构
Datastructure with equivalent power of heap and map
我想为元素e设计一个容器C
E有2个属性(优先级,名称),容器中的所有元素都有唯一的"名称"
我希望在容器C上尽可能高效地支持以下操作
- insert:-将element1(name1, priority1)插入到容器中:C.insert(元素(name1 priority1)
- update:-将name=name1作为优先级new1的元素更新优先级;C[name1] = priorityNew1
- delete:-删除name=name1的元素:C.delete(name1)
- 获取并移除优先级最高的元素:C.pop() 获取优先级最高的元素:C.peek()
基本上我想要map和heap的组合。映射元素的"名称",堆元素的"优先级"。最理想的情况是,我希望每个操作都是O(1)否则,插入、更新、删除的时间为O(log N), pop和peek的时间为O(1)也可以。
我能想到以下两种方法
1)使用元素的哈希映射,对名称进行哈希。所以插入、更新、删除都是0 (1)pop和peek是O(N),我们搜索整个容器的最高优先级。
2)使用SQLite,表'element'有两列'name'和'priority'。运行时间将基于SQLite实现。
我很想知道更多关于这个问题的想法,我正面临着一个与此相关的现实问题。
如果每个操作都可以接受O(logN)
,显然boost::bimap
就足够了。这就像一个双面 std::map
。您可以通过同时维护两个std::map
或编写自己的包装器来获得几乎相同的结果(但是为什么要这样做呢?)对于最小检索,具有自平衡的二叉搜索树具有O(logN)
,其效率略低于堆。
如果效率真的那么重要,你应该用实现你自己的容器,同时使用堆和散列映射。然后,当您在堆中进行交换时,在散列映射中维护从name
到堆数组中订阅的映射。这给了插入,删除,重分配优先级一个O(logN)
和O(1)
最小/最大优先级元素。(这不是一块蛋糕实现,但也不繁琐)
我不知道Boost是否适合你,但我会检查Boost多重索引。http://www.boost.org/doc/libs/1_53_0/libs/multi_index/doc/index.html
你可以在优先级上保留一个in索引,这样你就可以快速获取这些元素,也可以插入元素。我对MRU/LRU情况使用了类似的boost多索引。
#include <iostream>
#include <string>
#include <algorithm>
#include <boost/multi_index_container.hpp>
#include <boost/multi_index/ordered_index.hpp>
#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index/identity.hpp>
#include <boost/multi_index/member.hpp>
#include <boost/optional.hpp>
struct bypriority{};
struct byseq{};
struct MyElement{
typedef int priority_type;
typedef std::string name_type;
name_type name;
priority_type priority;
MyElement(const name_type& name, const priority_type& priority):name(name),priority(priority){};
};
std::ostream& operator<<(std::ostream& os, const MyElement& e){
os << "Name: " << e.name << " Priority: " << e.priority;
return os;
}
using namespace boost;
using namespace boost::multi_index;
template<typename Element>
struct Container{
typedef multi_index_container<
Element,
indexed_by<
//sequenced
sequenced<tag<byseq> >,
//ordered by priority
ordered_non_unique<tag<bypriority>,member<Element,typename Element::priority_type,&Element::priority>, std::greater<typename Element::priority_type> >
>
> Elements;
void insert(const Element& e){
typename Elements::template index<byseq>::type& list_view = elements.get<byseq>();
list_view.push_back(e);
}
boost::optional<Element> peek() const{
boost::optional<Element> res;
typename Elements::template index<bypriority>::type::iterator it = elements.get<bypriority>().begin();
if(it != elements.get<bypriority>().end()){
res.reset(*it);
}
return res;
}
boost::optional<Element> pop() {
boost::optional<Element> res;
typename Elements::template index<bypriority>::type& priority_index = elements.get<bypriority>();
typename Elements::template index<bypriority>::type::iterator it = elements.get<bypriority>().begin();
if(it != elements.get<bypriority>().end()){
res.reset(*it);
priority_index.erase(it);
}
return res;
}
void print_in_order(std::ostream& os) const{
typedef typename Elements::template index<byseq>::type elements_by_sequence;
for(typename elements_by_sequence::iterator it = elements.get<0>().begin(); it != elements.get<0>().end(); it++){
os << *it << std::endl;
}
}
protected:
Elements elements;
};
using namespace std;
int main(int argc, char *argv[]) {
Container<MyElement> c;
c.insert(MyElement("Bob",10));
c.insert(MyElement("Alice",100));
c.insert(MyElement("Fred",20));
c.print_in_order(std::cout);
cout << endl << "Highest Priority is " << endl << *c.peek() << endl;
boost::optional<MyElement> alice = c.pop();
if(alice){
cout << "Popped results are " << *alice << endl;
}
cout << endl << "Now the contents are" << endl;
c.print_in_order(std::cout);
}
将输出:
Name: Bob Priority: 10
Name: Alice Priority: 100
Name: Fred Priority: 20
Highest Priority is
Name: Alice Priority: 100
Popped results are Name: Alice Priority: 100
Now the contents are
Name: Bob Priority: 10
Name: Fred Priority: 20
- 链表,反向函数,数据结构
- 如何使用set实现无序数据结构?
- 我们可以将数据永久保存为数据结构吗?
- C++中的可变长度数组/数据结构
- 用于存储由空格分隔的字符串的 C++/C 数据结构
- 通过 NIF 从C++返回自定义数据结构
- 编译器上的策略数据结构不起作用
- 尝试构建"lock-free"数据结构C++
- 设计将引用元素移动到开头的数据结构.C++
- 在学习数据结构之前对STL有一个了解是好的吗?
- 如何解析表示树状数据结构的字符串
- 我对数据结构、双向链表有一些问题
- googletest:测试太大的数据结构
- C++中deque数据结构的大O是什么?
- 我可以使用哪种数据结构来处理这种方式
- 将文本文件解析为树状数据结构
- C++ 中具有 O(1) 搜索时间复杂度的数据结构
- 哪些存储了不完整类型的 STL 数据结构可以用作类成员?
- C++,您能否设计一种数据结构,将指针保存在连续内存中并且不会使它们失效?
- 具有堆和映射同等能力的数据结构