Максимальная куча против минимальной кучи для k-го наименьшего элемента

Мне сложно понять, почему в решениях для поиска k-го наименьшего элемента используется подход с максимальной кучей. И для k-го по величине элемента подход минимальной кучи. Разве не имеет смысла использовать минимальную кучу для поиска k-го наименьшего элемента, поскольку наименьший элемент всегда будет корневым? Итак, если мы хотим найти 3-й наименьший элемент, мы просто удаляем корень 2 раза, строим кучу и получаем 3-й наименьший элемент. В максимальной куче самый маленький не находится в корне, так почему лучше использовать? То же самое касается сортировки по возрастанию или убыванию чисел в массиве. Я вижу, что большинство людей используют максимальную кучу для подъема.


person Community    schedule 07.11.2018    source источник


Ответы (1)


Фактически, мы можем использовать как Min, так и Max heap, чтобы найти k-й наименьший элемент:

  1. Как вы описали, мы можем построить Min Heap, а затем извлечь k-й элемент в цикле.

or

  1. Мы можем построить Max Heap всего из k элементов. Затем мы просто сравниваем остальные элементы с корнем, заменяя корнем только те элементы, которые меньше корня, поэтому максимальная куча всегда имеет k наименьших элементов.
person Andriy Berestovskyy    schedule 07.11.2018
comment
Но как узнать, что вы находитесь на k-м наименьшем элементе? Разве вам не нужно было бы сравнивать все элементы в массиве до конца, прежде чем вы узнаете, является ли он k-м наименьшим? - person ; 07.11.2018
comment
@ mth1417 конечно, сначала вам нужно построить небольшую Max Heap с первыми k элементами, затем нам нужно сравнить остальную часть массива с Max Heap root. Но для создания Min Heap вам также необходимо сравнить все элементы массива. Кроме того, нам нужно извлечь k элементов, где k может быть размером с n ... - person Andriy Berestovskyy; 07.11.2018
comment
Зачем вам нужно сравнивать все элементы в минимальной куче, если самый маленький всегда находится в корне, вам просто нужно проверить root? - person ; 07.11.2018
comment
@ mth1417 нам нужно сравнить все элементы, чтобы построить Min Heap. Сложность создания кучи составляет O (n * log n), поэтому мы касаемся всех элементов, и для каждого элемента мы выполняем heapify, который равен O (log n). Для Max Heap мы делаем heapify только для k элементов, так что это O (k * log k), а затем мы просто сравниваем остальную часть массива с корнем Max Heap, иногда вызывая heapify только для k элементов. Таким образом, сложность для Max Heap составляет O (n * log k), а для Min Heap - O (n * log n) + O (k * log n) для извлечения k min элементов. - person Andriy Berestovskyy; 07.11.2018
comment
Извините, но я не понимаю, почему извлечение - это O (k * log n), когда извлечение всегда является только первым элементом - person ; 07.11.2018
comment
Еще один момент: с Max Heap мы можем мгновенно сохранить k наименьших элементов в онлайн-режиме - без полного массива. - person MBo; 07.11.2018
comment
@ mth1417 Извлечение вершины вызывает перестройку кучи за log (n) шагов. Извлечение k раз - klogn - person MBo; 07.11.2018
comment
@ mth1417 Потому что куча выглядит как двоичное дерево поиска, но на самом деле это не так. Каждый раз, когда мы вставляем / извлекаем элемент, куча должна быть скопирована, т.е. свойства кучи должны быть восстановлены. Сложность heapify составляет O (log n). Пожалуйста, загляните в Википедию для получения более подробной информации или добавьте еще один вопрос, если у вас остались вопросы: en.wikipedia. org / wiki / Binary_heap - person Andriy Berestovskyy; 07.11.2018
comment
Одно небольшое исправление: heapify, например. построение кучи из произвольного массива фактически занимает O (n) с использованием подхода sift / bubble down. Источник: stackoverflow.com/questions/9755721/ (это также отмечено в статье википедии о двоичной куче) - person KhalilRavanna; 17.07.2020
comment
@KhalilRavanna К сожалению, heapify не является построением кучи из произвольного массива. Heapify - это процесс восстановления свойства кучи, и он занимает O (log n). Пожалуйста, прочтите внимательно ссылки, все они говорят одно и то же ... - person Andriy Berestovskyy; 17.07.2020
comment
Хм, я нахожу терминологию изобилующей во многих местах, включая статью в Википедии, в которой уточняется то, что я описал. Не здорово, что терминология кажется смешанной. Похоже, вы описали именно то, о чем говорите, в своем комментарии, поэтому, пожалуйста, извините за мои возражения. en.wikipedia.org/wiki/Heap_(data_structure) - person KhalilRavanna; 19.07.2020