哈希表 VS 关联数组
Posted
技术标签:
【中文标题】哈希表 VS 关联数组【英文标题】:Hash tables VS associative arrays 【发布时间】:2011-03-09 05:41:57 【问题描述】:最近我在一本非常有名的书“Introduction to Algorithms”中读到了哈希表。我还没有在任何实际应用程序中使用它们,但我想。但我不知道如何开始。 谁能给我一些使用它的示例,例如,如何使用哈希表实现字典应用程序(如 ABBYY Lingvo)? 最后我想知道php中的哈希表和关联数组有什么区别,我的意思是我应该使用哪种技术以及在哪些情况下使用? 如果我错了(请原谅),请纠正我,因为实际上我是从哈希表开始的,我对它们只有基本(理论)知识。 非常感谢。
【问题讨论】:
见***.com/questions/2350361/… 【参考方案1】:php 数组基本上是哈希表
【讨论】:
编辑:啊 - 打败我 :) +1。 这就是我要找的 :) 没办法。哈希表需要某种冲突解决方法,而 php 数组没有。他们的冲突解决策略只是替换旧值,根据定义,这不是哈希表。 据我回忆,哈希表中的冲突解决是针对 hashed 键,而不是原始键(这应该如何工作?) 根据胡安的评论:数组可以实现为哈希表,但并不意味着它是哈希表。数组不需要碰撞检测,因此任何底层实现都可以忽略碰撞(只需通过赋值替换值)。【参考方案2】:在 PHP 中,关联数组被实现为哈希表,具有一些额外的功能。
但是从技术上讲,关联数组与哈希表并不相同——它只是在幕后部分实现哈希表。因为它的大部分实现都是一个哈希表,它可以做哈希表可以做的所有事情——但它也可以做更多。
例如,您可以使用 for 循环遍历关联数组,而哈希表则无法做到这一点。
因此,虽然它们相似,但关联数组实际上可以完成哈希表的超集 - 所以它们并不完全相同。将其视为哈希表和额外的功能。
代码示例:
使用关联数组作为哈希表:
$favoriteColor = array();
$favoriteColor['bob']='blue';
$favoriteColor['Peter']='red';
$favoriteColor['Sally']='pink';
echo 'bob likes: '.$favoriteColor['bob']."\n";
echo 'Sally likes: '.$favoriteColor['Sally']."\n";
//output: bob likes blue
// Sally likes pink
循环遍历关联数组:
$idTable=array();
$idTable['Tyler']=1;
$idTable['Bill']=20;
$idTable['Marc']=4;
//up until here, we're using the array as a hashtable.
//now we loop through the array - you can't do this with a hashtable:
foreach($idTable as $person=>$id)
echo 'id: '.$id.' | person: '.$person."\n";
//output: id: 1 | person: Tyler
// id: 20 | person: Bill
// id: 4 | person: Marc
特别注意在第二个示例中,每个元素的顺序是如何根据它们进入数组的顺序来维护的(Tyler,Bill Marc)。这是关联数组和哈希表之间的主要区别。哈希表不维护它所保存的项目之间的连接,而 PHP 关联数组则可以(您甚至可以对 PHP 关联数组进行排序)。
【讨论】:
嗯,这么简短的解释。所以他们绝对是一回事吗? @Bak 它们不是一般的,但它们是在 PHP 中的,它在数据结构上的表现有点快和松散,因为对性能的关注较少 @Michael 你让它听起来像是一个劣势?它使 PHP 与众不同,但我认为这是一个很好的区别。 @Bakhityor:你的最后一句话是完美的。不过,您不需要“忘记”哈希表——事实上,您已经了解哈希表真是太好了,因为现在您可以将这些知识应用于关联数组。我在回答中添加了一些示例,以便为您进一步澄清。 好答案。我想扩展它,不仅 PHP 中数组的底层实现是哈希表,它们还用于存储几乎所有其他内容:对象的属性和方法、函数、变量。等【参考方案3】:关联数组是一个数组,其中您不通过索引访问元素,而是通过键访问元素。这在内部如何工作是特定于实现的(没有规定它必须如何工作)。关联数组可以通过哈希表来实现(大多数实现都会这样做),但它也可以通过某种树结构或跳过列表来实现,或者算法只是遍历数组中的所有元素并查找键匹配(这会非常慢,但它有效)。
哈希表是一种存储数据的方法,其中值与键相关联,并且您打算在(通常几乎)恒定时间内找到键的值。这听起来与您对关联数组的期望完全一样,这就是为什么大部分时间哈希表都用于实现这些数组,但这不是强制性的。
【讨论】:
【参考方案4】:关联数组和哈希表的区别在于关联数组是一种数据类型,而哈希表是一种数据实现。显然,关联数组类型在当前许多编程语言中都非常重要:Perl、Python、PHP 等。哈希表是实现关联数组的主要方式,但并不是唯一的方式。关联数组是哈希表的主要用途,但并不是唯一的用途。所以并不是说它们是一样的,但是如果你已经有了关联数组,那么你通常不应该担心差异。
出于性能方面的原因,知道您最喜欢的语言的关联数组是作为散列实现的,这一点很重要。了解该实施的间接成本可能很重要。正如您在 C 中看到的那样,哈希表比线性数组更慢并且使用更多内存。
Perl 通过将关联数组称为“哈希”将这两个概念混为一谈。就像 Perl 的许多特性一样,它并没有完全错误,但它是草率的。
【讨论】:
【参考方案5】:PHP 中的数组实际上是一个有序映射,而不是哈希表。 map 和 hashtable 之间的主要区别在于无法记住添加元素的顺序。另一方面,哈希表比地图快得多。从 map 中获取元素的复杂度是 O(nlogn),而从 hashtable 中获取元素的复杂度是 O(1)。
【讨论】:
“从地图中获取元素的复杂性是 O(nlogn)”——这根本不是真的。即使对于 LinkedList,获取给定元素也只需 O(n)。更重要的是,如en.wikipedia.org/wiki/Hash_table 所述,PHP 中用于实现关联数组的哈希表的查找时间为 O(1) 正如here 在检查源代码后解释的那样,PHP 中的关联数组被实现为哈希表,其中 " 存储在哈希中的每个值都链接到存储在它之前的值和值存储在 " 之后作为链表。所以它为此使用了额外的内存,但是使用键访问某个元素的速度与通常的哈希表一样快,O(1),而不是更慢。以上是关于哈希表 VS 关联数组的主要内容,如果未能解决你的问题,请参考以下文章