C/C++

Программирование, пирамидальная сортировка

Если у меня есть масив :
5 4 1 3 2
То, мне нужно взять минимальный элемент (1) и поменять местами с первым элементом. Потом опять найти минимальный элемент (2), не обращая внимания на 1, и поменять его с вторым элементом масива (4). И так до тех пор, пока он не отсортируется? В этом суть пирамидальной сортировки?
В этом суть всех сортировок выбором: это не одна, а целый класс разных сортировок.
А название конкретной сортировки зависит от способа поиска минимального элемента.
Если это простой последовательный просмотр всех оставшихся элементов массива - получаем сортировку простым выбором.
А если сначала перетасовываем элементы массива в пирамиду (кучу), а потом выбираем элементы из этой пирамиды - получаем пирамидальную сортировку.
Сортировка простым выбором - очень просто и медленно.
Пирамидальная сортировка - существенно сложнее и быстро.
Классическая пирамидальная сортировка с подробным объяснением: https://habr.com/ru/company/edison/blog/495420/
Улучшенная (по скорости работы) пирамидальная сортировка: https://habr.com/ru/company/edison/blog/509330/
JK
Joomart Karabekov
59 932
Лучший ответ
Алгоритм пирамидальной сортировки в порядке по возрастанию:

Постройте max-heap из входных данных.
На данном этапе самый большой элемент хранится в корне кучи. Замените его на последний элемент кучи, а затем уменьшите ее размер на 1. Наконец, преобразуйте полученное дерево в max-heap с новым корнем.
Повторяйте вышеуказанные шаги, пока размер кучи больше 1.

#include

using namespace std;

// Процедура для преобразования в двоичную кучу поддерева с корневым узлом i, что является
// индексом в arr[]. n - размер кучи

void heapify(int arr[], int n, int i)
{
int largest = i;
// Инициализируем наибольший элемент как корень
int l = 2*i + 1; // левый = 2*i + 1
int r = 2*i + 2; // правый = 2*i + 2

// Если левый дочерний элемент больше корня
if (l < n && arr[l] > arr[largest])
largest = l;

// Если правый дочерний элемент больше, чем самый большой элемент на данный момент
if (r < n && arr[r] > arr[largest])
largest = r;

// Если самый большой элемент не корень
if (largest != i)
{
swap(arr[i], arr[largest]);

// Рекурсивно преобразуем в двоичную кучу затронутое поддерево
heapify(arr, n, largest);
}
}

// Основная функция, выполняющая пирамидальную сортировку
void heapSort(int arr[], int n)
{
// Построение кучи (перегруппируем массив)
for (int i = n / 2 - 1; i >= 0; i--)
heapify(arr, n, i);

// Один за другим извлекаем элементы из кучи
for (int i=n-1; i>=0; i--)
{
// Перемещаем текущий корень в конец
swap(arr[0], arr[i]);

// вызываем процедуру heapify на уменьшенной куче
heapify(arr, i, 0);
}
}

/* Вспомогательная функция для вывода на экран массива размера n*/
void printArray(int arr[], int n)
{
for (int i=0; i<n; ++i)
cout << arr[i] << " ";
cout << "\n";
}

// Управляющая программа
int main()
{
int arr[] = {12, 11, 13, 5, 6, 7};
int n = sizeof(arr)/sizeof(arr[0]);

heapSort(arr, n);

cout << "Sorted array is \n";
printArray(arr, n);
}