在我看到的每个哈希表实现中,哈希用于选择"桶"这是一个项目列表,然后迭代该列表,直到找到我们想要的项目。
我的问题是为什么它总是一个清单?从我听到的情况来看,矢量几乎总是更有效率,那么为什么不使用矢量作为桶呢?列表的某些属性是否适合用作哈希表中的存储区?
我在这里使用了C ++术语,但它确实适用于任何语言。
答案 0 :(得分:1)
哈希表用于速度受关注的地方。
与std::vector
相比,添加std::list
中的元素要慢得多,而std::vector
实现为双向链接列表。
向std::list
添加元素时,如果向量大小超过向量容量,则必须在内存中移动所有元素。在std::vector
中,只分配新元素的内存,并且必须调整最后一个元素的下一个指针。
从std::list
中删除元素时,必须在内存中移动所有后续元素。在 public Node buildSecurityHeader(String username, String password)
throws WSSecurityException, ParserConfigurationException, SAXException, IOException{
//XML Document builder with a root node
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource inStream = new InputSource();
inStream.setCharacterStream(new StringReader("<root></root>"));
Document document = builder.parse(inStream);
//<wsse:UsernameToken>
WSSecUsernameToken usernametoken = new WSSecUsernameToken();
usernametoken.setPasswordType(WSConstants.PASSWORD_DIGEST);
usernametoken.setUserInfo(username, password);
//<wsse:Security>
WSSecHeader secHeader = new WSSecHeader(document);
secHeader.insertSecurityHeader();
//Generates the Document with <root><Header><wsse:Security>...
usernametoken.build(document, secHeader);
//Extract the desired node
Node securityNode = document.getElementsByTagName("wsse:Security").item(0);
return securityNode;
}
中,只需要调整上一个和下一个指针。
可能是另一个原因:如果使用std :: list,元素将永远不会在内存中移动,并且一旦将元素添加到地图中,您就可以使用裸指针来寻址元素。当使用std :: vector时,如果向量调整大小并且所有裸指针都悬空,则移动元素
OOT:另一种解决方案是根本不使用桶的列表:如果新元素将散列到位置7并且此位置已被占用,则新元素将被写入位置8(依此类推) 。如果哈希表几乎为空,则此解决方案非常快,如果表几乎已满,则此缓慢。如果元素的数量超过散列表大小,则必须调整大小并重新组织,这是一项非常昂贵的操作。