В чем разница между кучей и BST?
Когда использовать кучу, а когда использовать BST?
Если вы хотите получить элементы в отсортированном виде, лучше ли BST по сравнению с кучей?
В чем разница между кучей и BST?
Когда использовать кучу, а когда использовать BST?
Если вы хотите получить элементы в отсортированном виде, лучше ли BST по сравнению с кучей?
Резюме
Type BST (*) Heap
Insert average log(n) 1
Insert worst log(n) log(n) or n (***)
Find any worst log(n) n
Find max worst 1 (**) 1
Create worst n log(n) n
Delete worst log(n) log(n)
Все средние значения времени в этой таблице такие же, как и их худшие времена, за исключением вставки.
*
: везде в этом ответе BST == Balanced BST, поскольку несбалансированный отстой асимптотически**
: используя тривиальную модификацию, описанную в этом ответе***
: log(n)
для кучи дерева указателей, n
для кучи динамического массиваПреимущества двоичной кучи над BST
среднее время вставки в двоичную кучу O(1)
, для BST O(log(n))
. Это смертоносное свойство куч.
Существуют также другие кучи, которые достигают O(1)
амортизированной (более сильной), например кучи Фибоначчи, и даже хуже случай, как очередь Бродала, хотя они могут оказаться непрактичными из-за неасимптотической производительности: Используются ли на практике кучи Фибоначчи или очереди Бродала? < / а>
двоичные кучи могут быть эффективно реализованы поверх динамических массивов или деревьев на основе указателей, только BST деревья на основе указателей. Таким образом, для кучи мы можем выбрать более эффективную реализацию массива, если мы можем позволить себе периодические задержки при изменении размера.
Создание двоичной кучи O(n)
худший случай, O(n log(n))
для BST.
Преимущество BST перед двоичной кучей
поиск произвольных элементов - O(log(n))
. Это потрясающая особенность BST.
Для кучи это обычно O(n)
, за исключением самого большого элемента, который равен O(1)
.
Ложное преимущество кучи над BST
куча O(1)
, чтобы найти макс, BST O(log(n))
.
Это распространенное заблуждение, потому что тривиально изменить BST, чтобы отслеживать самый большой элемент, и обновлять его всякий раз, когда этот элемент может быть изменен: при вставке более крупного свопа при удалении найдите второй по величине. Можно ли использовать двоичное дерево поиска для имитации работы кучи? (упомянуто Йео).
Фактически, это ограничение кучи по сравнению с BST: единственный эффективный поиск - это поиск самого большого элемента.
Среднее значение вставки двоичной кучи O(1)
Источники:
Интуитивный аргумент:
В двоичной куче увеличение значения данного индекса также равно 18_ по той же причине. Но если вы хотите это сделать, вполне вероятно, что вы захотите обновлять дополнительный индекс по операциям с кучей Как реализовать операцию уменьшения ключа O (logn) для приоритетной очереди на основе min-heap? например, для Дейкстры. Возможно без дополнительных затрат времени.
Тест вставки стандартной библиотеки GCC C ++ на реальном оборудовании
Я протестировал C ++ std::set
(Красно-черное дерево BST) и std::priority_queue
(куча динамического массива), чтобы проверить, прав ли я насчет времени вставки, и вот что у меня получилось:
Интерпретация:
куча по-прежнему постоянна, но теперь мы видим более подробно, что есть несколько строк, и каждая более высокая строка более разреженная.
Это должно соответствовать задержкам доступа к памяти, которые выполняются для более высоких и более высоких вставок.
TODO Я не могу полностью интерпретировать BST, поскольку он не выглядит таким логарифмическим и несколько более постоянным.
Однако с этой более подробной информацией мы можем видеть несколько отдельных линий, но я не уверен, что они представляют: я ожидал, что нижняя линия будет тоньше, поскольку мы вставляем верхнюю нижнюю?
Проверено с помощью этой person Ciro Santilli 新疆再教育营六四事件ۍ schedule 09.04.2015
O(1)
.
- person Ciro Santilli 新疆再教育营六四事件ۍ 07.08.2018
Куча просто гарантирует, что элементы на более высоких уровнях больше (для max-heap) или меньше (для min-heap), чем элементы на более низких уровнях, тогда как BST гарантирует порядок (от «левого» к «правому»). Если вам нужны отсортированные элементы, используйте BST.
[1, 5, 9, 7, 15, 10, 11]
представляет допустимую минимальную кучу, но 7
на уровне 3 меньше, чем 9
на уровне 2. Для визуализации см., Например, элементы 25
и 19
в образце изображения из Википедии для кучи. (Также обратите внимание, что отношения неравенства между элементами не являются строгими, поскольку элементы не обязательно уникальны.)
- person Daniel Andersson; 23.08.2015
Когда использовать кучу, а когда использовать BST
Куча лучше подходит для findMin / findMax (O(1)
), тогда как BST хорош для всех находок (O(logN)
). Вставка O(logN)
для обеих структур. Если вас интересует только findMin / findMax (например, связанный с приоритетом), используйте кучу. Если вы хотите, чтобы все было отсортировано, используйте BST.
Первые несколько слайдов из здесь очень ясно объясняют вещи.
Как упоминалось другими, Heap может выполнять findMin
или findMax
в O (1), но не оба в одной структуре данных. Однако я не согласен с тем, что Heap лучше в findMin / findMax. Фактически, с небольшими изменениями, BST может выполнять оба findMin
и findMax
в O (1).
В этом модифицированном BST вы отслеживаете минимальный и максимальный узел каждый раз, когда выполняете операцию, которая потенциально может изменить структуру данных. Например, в операции вставки вы можете проверить, больше ли минимальное значение, чем вновь вставленное значение, а затем присвоить минимальное значение вновь добавленному узлу. Тот же метод можно применить к максимальному значению. Следовательно, этот BST содержит эту информацию, которую вы можете получить за O (1). (то же, что и двоичная куча)
В этом BST (сбалансированный BST), когда вы pop min
или pop max
, следующее минимальное значение, которое должно быть присвоено, является преемником минимального узла, тогда как следующее максимальное значение, которое должно быть назначено, является предшественником максимального узла. Таким образом, он выполняется за O (1). Однако нам нужно повторно сбалансировать дерево, поэтому оно все равно будет работать O (log n). (то же, что и двоичная куча)
Мне было бы интересно услышать вашу мысль в комментарии ниже. Спасибо :)
Перекрестная ссылка на аналогичный вопрос Можно ли использовать двоичное дерево поиска для имитации работы кучи? для более подробного обсуждения моделирования кучи с помощью BST.
popMin
или popMax
это не O (1), а O (log n), потому что это должен быть сбалансированный BST, который необходимо повторно балансировать при каждой операции удаления. Следовательно, это то же самое, что и двоичная куча popMin
или popMax
, которая запускает O (log n)
- person Yeo; 22.11.2014
Бинарное дерево поиска использует определение: для каждого узла узел слева от него имеет меньшее значение (ключ), а узел справа от него имеет большее значение (ключ).
Где в качестве кучи, будучи реализацией двоичного дерева, используется следующее определение:
Если A и B - узлы, где B - дочерний узел A, тогда значение (ключ) A должно быть больше или равно значению (ключу) B. То есть ключ (A) ≥ key (B ).
http://wiki.answers.com/Q/Difference_between_binary_search_tree_and_heap_tree
Сегодня я задавал тот же вопрос на экзамене, и я понял его правильно. улыбка ... :)
Другое использование BST вместо кучи; из-за важной разницы:
Использование BST в куче. Допустим, мы используем структуру данных для хранения времени посадки рейсов. Мы не можем запланировать рейс на посадку, если разница во времени посадки меньше "d". И предположим, что многие рейсы запланированы для приземления в структуре данных (BST или Heap).
Теперь мы хотим запланировать еще один рейс, который приземлится в t. Следовательно, нам нужно вычислить разницу t с его преемником и предшественником (должно быть> d). Таким образом, для этого нам понадобится BST, который делает это быстро, т.е. за O (logn), если сбалансировано.
ИЗМЕНЕНО:
Сортировка BST занимает O (n) времени для печати элементов в отсортированном порядке (Inorder Traversal), в то время как Heap может сделать это за O (n logn) времени. Куча извлекает минимальный элемент и повторно заполняет массив, что заставляет его выполнять сортировку за время O (n logn).
from unsorted to sorted sequence. O(n) time for inorder traversal of a BST, which gives sorted sequence.
Что ж, от несортированной последовательности к BST я не знаю метода, основанного на сравнении ключей с временем менее O (n logn), который доминирует над частью BST для последовательности. (В то время как существует конструкция кучи O (n).) Я бы счел справедливым (если не бессмысленным) утверждать, что кучи близки к несортированности, а BST отсортированы.
- person greybeard; 01.04.2015
Вставка всех n элементов из массива в BST занимает O (n logn). n элементов в массиве могут быть вставлены в кучу за O (n) раз. Что дает куче несомненное преимущество
Куча просто гарантирует, что элементы на более высоких уровнях больше (для max-heap) или меньше (для min-heap), чем элементы на более низких уровнях.
Мне нравится приведенный выше ответ, и я помещаю свой комментарий только в соответствии с моими потребностями и использованием. Мне пришлось получить список n местоположений, чтобы найти расстояние от каждого местоположения до конкретной точки, скажем (0,0), а затем вернуть местоположения a m, имеющие меньшее расстояние. Я использовал очередь приоритетов, которая является кучей. Для определения расстояний и помещения в кучу мне потребовалось n (log (n)) n местоположений log (n) на каждую вставку. Тогда для получения m с кратчайшими расстояниями потребовалось m (log (n)) m-location log (n) удалений скопления.
Если бы мне пришлось сделать это с помощью BST, мне потребовалось бы n (n) вставки в худшем случае. (Скажем, первое значение очень меньше, а все остальные идут последовательно все длиннее и длиннее, а дерево охватывает только правый дочерний элемент или левый дочерний элемент. в случае меньшего и меньшего.Минимальное время заняло бы O (1), но снова мне пришлось сбалансировать.Так что из моей ситуации и всех вышеперечисленных ответов я получил, когда вы только после значений с минимальным или максимальным приоритетом для кучи.