Если у меня есть масив :
5 4 1 3 2
То, мне нужно взять минимальный элемент (1) и поменять местами с первым элементом. Потом опять найти минимальный элемент (2), не обращая внимания на 1, и поменять его с вторым элементом масива (4). И так до тех пор, пока он не отсортируется? В этом суть пирамидальной сортировки?
C/C++
Программирование, пирамидальная сортировка
В этом суть всех сортировок выбором: это не одна, а целый класс разных сортировок.
А название конкретной сортировки зависит от способа поиска минимального элемента.
Если это простой последовательный просмотр всех оставшихся элементов массива - получаем сортировку простым выбором.
А если сначала перетасовываем элементы массива в пирамиду (кучу), а потом выбираем элементы из этой пирамиды - получаем пирамидальную сортировку.
Сортировка простым выбором - очень просто и медленно.
Пирамидальная сортировка - существенно сложнее и быстро.
Классическая пирамидальная сортировка с подробным объяснением: https://habr.com/ru/company/edison/blog/495420/
Улучшенная (по скорости работы) пирамидальная сортировка: https://habr.com/ru/company/edison/blog/509330/
А название конкретной сортировки зависит от способа поиска минимального элемента.
Если это простой последовательный просмотр всех оставшихся элементов массива - получаем сортировку простым выбором.
А если сначала перетасовываем элементы массива в пирамиду (кучу), а потом выбираем элементы из этой пирамиды - получаем пирамидальную сортировку.
Сортировка простым выбором - очень просто и медленно.
Пирамидальная сортировка - существенно сложнее и быстро.
Классическая пирамидальная сортировка с подробным объяснением: https://habr.com/ru/company/edison/blog/495420/
Улучшенная (по скорости работы) пирамидальная сортировка: https://habr.com/ru/company/edison/blog/509330/
Серый Кульчицкий
Спасибо
Алгоритм пирамидальной сортировки в порядке по возрастанию:
Постройте 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);
}
Постройте 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);
}
Похожие вопросы
- Сравнение скорости сортировки выбором и сортировки слиянием (SelectionSort vs MergeSort)
- Выполните сортировку массивов ТРЕМЯ СПОСОБАМИ: методом пузырька, прямого поиска и быстрой сортировкой. С++
- Выполните сортировку массивов ТРЕМЯ СПОСОБАМИ: методом пузырька, прямого поиска и быстрой сортировкой. С++
- Задача на сортировку структур. Язык C++.
- Проблемы с сортировкой массива методом пузырька.
- КОНТРОЛЬНЫЕ ЗАДАНИЯ ПО СОРТИРОВКЕ МАССИВОВ
- С++ Сортировка массива
- Алгоритмы STL, sort, первичный и вторичный ключи для сортировки.
- Сортировка выбором. Язык C++. Помощь с кодом.
- Алгоритмы. Бинарная сортировка