#java #algorithm #heapsort
#java #алгоритм #сортировка по кучам
Вопрос:
Я знаю, как сортировать массив на месте, используя свойство heapsort и max-heap.
Но я не могу придумать, как я мог бы отсортировать его на месте, используя свойство min-heap.
Я могу отсортировать его с помощью минимальной кучи, используя временный промежуточный массив, например
public static int[] heapSort2(int[] array){
buildMinHeap(array);
int [] temp = new int[array.length];
for(int i = 0; i < array.length; i ){
temp[i] = extractMin(array);
}
return temp;//returns array input sorted
}
Но я не могу придумать способ сделать это без использования temp. Возможно ли это, или минимальная куча предназначена только для очередей с приоритетом?
Комментарии:
1. классическая кучная сортировка сортирует массив путем разделения на 2 части, отсортированную и несортированную. На каждом шаге увеличивается отсортированная часть и уменьшается несортированная.
2. @bestsss: это сортировка по вставке
3. @user384706 Когда сортировка по кучам реализована на месте, она также выглядит так же на этапе вставки.
Ответ №1:
Сортировка на месте с использованием минимальной кучи симметрична сортировке с максимальной кучей.
Предположим, что вы сортируете в порядке возрастания, и у вас есть массив с максимальной кучей, с корнем всегда в первом элементе (индекс 1), и вы выполняете один шаг сортировки, перемещая корень на место последнего листа (который является самым правым элементом, который еще не отсортирован), превращая этот лист в новый корень и помещая его в кучу.
Затем вы сортируете в порядке возрастания, используя массив min-heap, имея корень всегда в последнем элементе (индекс N), и вы выполняете один шаг сортировки, перемещая корень на место последнего листа (который является крайним левым элементом, который еще не отсортирован), создавая этот листновый корень и погружение его в кучу.
Уравнения для получения индексов родительского, левого и правого дочерних элементов в такой куче разные. В первом случае, предполагая индексы 1-> N, уравнения:
parent(i) = floor(i / 2)
leftchild(i) = 2 * i
rightchild(i) = 2 * i 1
В последнем, обратном случае минимальной кучи, уравнения получаются путем изменения индексов на входе и выходе вышеуказанного:
parent(i) = N 1 - floor((N 1 - i) / 2)
leftchild(i) = N 1 - (2 * (N 1 - i))
rightchild(i) = N 1 - (2 * (N 1 - i) 1)
Вы можете видеть, что последние уравнения выглядят уродливо по сравнению с первыми (но их можно упростить). Поэтому при сортировке в порядке возрастания вам лучше всего использовать только максимальную кучу, а не минимальную кучу. Используйте минимальную кучу только тогда, когда вы хотите отсортировать в порядке убывания — в той же ориентации, что и при использовании максимальной кучи при сортировке в порядке возрастания (корень по первому элементу).
Комментарии:
1. Почему бы нам не создать минимальную кучу и не выполнить над ней 1 цикл поиска пузырьков? Разве это не сэкономит нам время O (log (n))?