Хеш-таблицы VS ассоциативные массивы

84

Недавно я прочитал о хэш-таблицах в очень известной книге « Введение в алгоритмы ». Я еще не использовал их ни в каких реальных приложениях, но хочу. Но я не знаю, с чего начать.
Может ли кто-нибудь дать мне несколько примеров его использования, например, как реализовать словарное приложение (например, ABBYY Lingvo) с использованием хеш-таблиц?
И, наконец, я хотел бы знать, в чем разница между хеш-таблицами и ассоциативными массивами в PHP, я имею в виду, какую технологию мне следует использовать и в каких ситуациях?
Если я ошибаюсь (прошу прощения), поправьте меня, потому что на самом деле я начинаю с хеш-таблиц и у меня есть только базовые (теоретические) знания о них.
Большое спасибо.

Бахтиёр
источник

Ответы:

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

Обратите особое внимание на то, как во втором примере поддерживается порядок каждого элемента (Тайлер, Билл Марк) на основе порядка, в котором они были введены в массив. Это главное различие между ассоциативными массивами и хэш-таблицами. Хэш-таблица не поддерживает связи между элементами, которые она содержит, тогда как ассоциативный массив PHP делает это (вы даже можете отсортировать ассоциативный массив PHP).

Кулачок
источник
3
Хммм, такое короткое объяснение. Значит, они АБСОЛЮТНО одно и то же?
Бахтиёр
2
@Bak В общем, их нет, но они написаны на PHP, который работает немного быстро и неаккуратно со структурами данных, так как производительность меньше беспокоит
Майкл Мрозек
Понятно, но почему в данном случае так много алгоритмов для хэш-функций и тому подобного, если хеш-функция = массивы?
Бахтиёр
4
@ Майкл, ты говоришь, что это недостаток? Это отличает PHP от других, но я думаю, что это хорошая разница.
1
@Bakhityor: Твоя последняя фраза идеальна. Однако вам не нужно «забывать» о хэш-таблицах - на самом деле здорово, что вы уже разбираетесь в хэш-таблицах, потому что теперь вы можете применять эти знания к ассоциативным массивам. Я добавляю несколько примеров к своему ответу, чтобы прояснить вам ситуацию.
Cam
21

Массивы php - это в основном хеш-таблицы

Сергей Еремин
источник
Edit: Ах - опередите меня :) +1.
Cam
вот что я искал :)
Файзан
11
ни за что. Для хеш-таблицы потребуется какое-то разрешение конфликтов, которого нет в массивах php. Их стратегия разрешения конфликтов просто заменяет старое значение, а это не хеш-таблица по определению.
Хуан
4
Насколько я помню, разрешение коллизий в хеш-таблицах предназначено для хешированного ключа, а не для исходного ключа (как это вообще должно работать?)
Эмануэль Остер
18

Разница между ассоциативным массивом и хеш-таблицей заключается в том, что ассоциативный массив является типом данных, а хеш-таблица - реализацией данных. Очевидно, что тип ассоциативного массива очень важен для многих современных языков программирования: Perl, Python, PHP и т. Д. Хеш-таблица - это основной способ реализации ассоциативного массива, но не совсем единственный. А ассоциативные массивы - это основное, но не единственное применение хэш-таблиц. Так что дело не в том, что они одинаковы, но если у вас уже есть ассоциативные массивы, вам обычно не стоит беспокоиться о разнице.

По соображениям производительности может быть важно знать, что ваши ассоциативные массивы на вашем любимом языке реализованы в виде хэшей. И может быть важно иметь некоторое представление о накладных расходах на эту реализацию. Хеш-таблицы медленнее и используют больше памяти, чем линейные массивы, как вы видите их в C.

Perl объединяет эти две концепции вместе, называя ассоциативные массивы «хешами». Как и многие другие возможности Perl, это не совсем неправильно, но это небрежно.

Грег Куперберг
источник
7

Массив в PHP - это фактически упорядоченная карта, а не хеш-таблица. Основное различие между картой и хеш-таблицей заключается в невозможности запомнить порядок, в котором были добавлены элементы. С другой стороны, хэш-таблицы намного быстрее, чем карты. Сложность выборки элемента из карты составляет O (nlogn), а из хеш-таблицы - O (1).

WoZ
источник
4
«Сложность получения элемента с карты составляет O (nlogn)» - это просто неправда. Даже для LinkedList выборка данного элемента составляет всего O (n). Более того, как указано на en.wikipedia.org/wiki/Hash_table , хэш-таблица, используемая в PHP для реализации ассоциативного массива, имеет поиск O (1)
StackG
1
Как объясняется здесь после проверки исходного кода, ассоциативные массивы в PHP реализованы как хеш-таблицы, где «каждое значение, хранящееся в хеш- коде, связано со значением, сохраненным перед ним, и значением, сохраненным после», в виде связанного списка. Таким образом, он использует для этого дополнительную память, но доступ к определенному элементу с помощью ключа происходит так же быстро, как и обычная хеш-таблица, O (1), но не медленнее.
Леопольдо Санчик
2

Ассоциативный массив - это массив, в котором вы получаете доступ к элементам не по индексу, а по ключу. Как это работает внутри, зависит от конкретной реализации (нет правила, как это должно работать). Ассоциативный массив может быть реализован с помощью хэш-таблицы (большинство реализаций это делают), но он также может быть реализован с помощью какой-то древовидной структуры или списка пропуска, или алгоритм просто выполняет итерацию по всем элементам в массиве и ищет ключ это соответствует (это было бы ужасно медленно, но это работает).

Хеш-таблица - это способ хранения данных, в которых значения связаны с ключами и где вы собираетесь найти значения для ключей в течение (обычно почти) постоянного времени. Это звучит в точности так, как вы ожидаете от ассоциативного массива, поэтому большую часть времени для реализации этих массивов используются хеш-таблицы, но это не обязательно.

Mecki
источник