哈希表VS关联数组


84

最近,我在一本非常著名的书“算法简介”中阅读了有关散列表的信息。我还没有在任何实际的应用程序中使用它们,但是想要。但是我不知道如何开始。 谁能给我一些使用它的示例,例如,如何使用哈希表实现字典应用程序(例如ABBYY Lingvo)? 最后,我想知道PHP中的哈希表和关联数组之间的区别是什么,我的意思是应该使用哪种技术以及在哪种情况下? 如果我错了(请原谅),请纠正我,因为实际上我是从哈希表开始的,并且我对哈希表只有基本的(理论上的)知识。 非常感谢。




Answers:


123

在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关联数组进行排序)。


3
嗯,这么简短的解释。所以他们绝对是同一回事吗?
巴赫蒂奥尔

2
@Bak不是一般的,但是它们使用PHP,由于对性能的关注较少,因此它在数据结构中起着快速和松散的作用
Michael Mrozek

我知道了,但是在这种情况下,如果hash function = arrays,为什么会有这么多算法用于哈希函数和类似的东西?
巴赫蒂奥尔

4
@Michael您听起来像个劣势吗?它使PHP与众不同,但我认为这是一个很好的区别。

1
@Bakhityor:您的最后一句话很完美。但是,您不需要“忘记”哈希表-实际上,您已经了解哈希表非常有用,因为现在您可以将这些知识应用于关联数组。我在答案中添加了一些示例,以进一步为您澄清问题。
凸轮

21

php数组基本上是哈希表


编辑:啊-击败我:) +1。
凸轮

那就是我想要的东西:)
Faizan 2013年

10
没门。哈希表需要某种冲突解决方案,而php数组则没有。他们的冲突解决策略只是替换旧值,而就其定义而言,这不是哈希表。
胡安

4
据我所知,哈希表中的冲突解决方案是针对哈希键的,而不是原始键的(这怎么工作?)
Emanuel Oster

18

关联数组和哈希表之间的区别在于,关联数组是数据类型,而哈希表是数据实现。显然,关联数组类型在许多当前的编程语言中非常重要:Perl,Python,PHP等。哈希表是实现关联数组的主要方法,但不是唯一的方法。关联数组是哈希表的主要用途,但不是唯一的用途。因此,并不是它们是相同的,而是如果您已经具有关联数组,则通常不必担心它们之间的差异。

出于性能原因,了解自己喜欢的语言中的关联数组已实现为散列很重要。对实现的开销成本有所了解可能很重要。哈希表比线性数组要慢,并且使用的内存要比线性数组多,就像您在C中看到的那样。

Perl通过将关联数组称为“哈希”来将这两个概念混在一起。像Perl的许多功能一样,这不是很错误,但是它很草率。


7

PHP中的数组实际上是有序映射,而不是哈希表。map和hashtable之间的主要区别在于无法记住已添加的元素的顺序。另一方面,哈希表比映射快得多。从映射中获取元素的复杂度为O(nlogn),从哈希表中获取元素的复杂度为O(1)。


4
“从映射中获取元素的复杂度为O(nlogn)”-事实并非如此。即使对于LinkedList,获取给定元素也仅为O(n)。此外,如en.wikipedia.org/wiki/Hash_table所述,PHP中用于实现关联数组的哈希表的查找值为O(1)
StackG 2015年

1
如所解释这里检查的源代码之后,在PHP关联数组被实现为哈希表,其中“存储在哈希每个值被链接到之前和之后存储的值存储的值”作为链接列表。因此,它为此使用了额外的内存,但是使用键访问特定元素的速度与通常的哈希表O(1)一样快,但并不慢。
Leopoldo Sanczyk

2

关联数组是您不通过索引而是通过键访问元素的数组。它在内部如何工作是特定于实现的(没有规则必须如何工作)。关联数组可以通过哈希表来实现(大多数实现会做到这一点),但是它也可以通过某种树结构或跳过列表来实现,或者算法仅对数组中的所有元素进行迭代并查找键匹配(这确实很慢,但是可以工作)。

哈希表是一种存储数据的方法,其中值与键相关联,并且打算在(通常几乎是)恒定时间内找到键的值。这听起来与您对关联数组的期望完全一样,这就是为什么大多数时间哈希表用于实现这些数组的原因,但这不是强制性的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.