C++ 带STL的哈希列表-我可以将STL列表中的一个项目指向另一个项目吗?
假设我有一个:C++ 带STL的哈希列表-我可以将STL列表中的一个项目指向另一个项目吗?,c++,stl,C++,Stl,假设我有一个: std::vector<std::list<Node> > 向量单元对应于用于快速查找的哈希函数值。其思想是将元素插入到向量中,但仍然使用节点->下一个成员将它们链接在一起。因此,您有一个列表,在该列表中,可以使用哈希函数通过键高效地查找元素,以找到要从中开始的正确向量单元 不管怎样,把这些都放在一边。我的问题是: 我可以让我的Node::next指针指向列表中的其他节点(无论是同一个节点,还是来自不同向量单元的另一个节点)而不会引起问题吗?我不确定列表
std::vector<std::list<Node> >
向量单元对应于用于快速查找的哈希函数值。其思想是将元素插入到向量中,但仍然使用节点->下一个成员将它们链接在一起。因此,您有一个列表,在该列表中,可以使用哈希函数通过键高效地查找元素,以找到要从中开始的正确向量单元
不管怎样,把这些都放在一边。我的问题是:
我可以让我的Node::next指针指向列表中的其他节点(无论是同一个节点,还是来自不同向量单元的另一个节点)而不会引起问题吗?我不确定列表的标准库实现是否允许这样做。我似乎遇到了问题(我的代码在这里不可访问),我想看看这是否是原因。STL列表是双重链接的,并且有私有的上一个和下一个指针。元素中的下一个指针将与列表的下一个指针无关,因此它可以是您想要的任何东西。你必须自己管理它。看起来您正在使用哈希冲突的链表实现一个哈希(clippy说)。你看过地图容器了吗?如果你想让它指向列表中的其他节点,那是完全可行的,是的。然而,我会提出一个不同的设计:一个
std::list
和一个std::unordered_map
,这两个类的成员的唯一目的是保持两个容器的同步。这应该比你目前的计划更容易、更安全、更快
在两个列表中添加和删除对象很容易:
std::unordered_map<int, std::list<int>::iterator> fast;
std::list<int> linked;
void add(int data) {
fast[data] = linked.insert(linked.end(), data);
};
std::list<int>::iterator erase(std::list<int>::iterator iter) {
fast.erase(*iter);
return linked.erase(iter);
}
std::无序映射快速;
列表链接;
无效添加(整数数据){
fast[data]=linked.insert(linked.end(),data);
};
标准::列表::迭代器擦除(标准::列表::迭代器iter){
快速擦除(*iter);
返回链接擦除(iter);
}
据我所知,std::list和std::vector分配了一定数量的内存,并且在添加项时,如果没有足够的空间容纳所有项,可能会将所有项移动到内存的不同部分。这显然会导致这段代码中出现问题。我知道std::vector这样做是因为它需要连续内存——但我不希望从列表中看到它,因为它会涉及额外的元素复制,而不会带来任何好处。您确定列表会这样做吗?@nijansen您关于std::vector
的说法是正确的,但是std::list
不会移动项目。(当然,如果列表
位于向量
中,则可能会复制列表
。)您可以使用智能指针来解决此限制,但这可能会对节点结构造成过大影响。不如自己编写一个满足所有需求的容器类?@nijansen:True用于vector,而不是list。对列表成员的所有引用都可以安全地修改列表(除非删除了被引用的实际成员)。但是请注意:在这种情况下,由于列表可能会随着向量的放大而被复制(C++03在C++11中不是真的),所以列表的旧版本可能会被销毁。该死,愚蠢的电话。有人能把这些符号改成反勾号以便正确显示吗?我没有修复这些符号,因为这些内容让我感到困惑-其他人可以这样做:我能把最后一个元素的指针推回到列表中,这样我就可以存储它以备以后使用吗?我想我知道,但这似乎是不正常的部分。@w00te:我添加了简单的函数来添加和删除。如何将指向最后一个元素的指针返回到列表中,以便存储它以备将来使用?我想我知道,但这似乎是不正确的部分。list::end方法给出了列表的最后一个元素。我实际上解决了我的问题。我一直在使用&list.back(),这很好。我的问题实际上只是遍历函数中的一个愚蠢错误:(
std::unordered_map<int, std::list<int>::iterator> fast;
std::list<int> linked;
void add(int data) {
fast[data] = linked.insert(linked.end(), data);
};
std::list<int>::iterator erase(std::list<int>::iterator iter) {
fast.erase(*iter);
return linked.erase(iter);
}