Задан массив целых чисел.
Переставьте его элементы так, чтобы получилась max-куча.
Вход.
В первой строке задано количество элементов массива n (n ≤ 1000).
Во второй строке
содержится n целых чисел, каждое по модулю не
превышает 106.
Выход.
Выведите переставленный массив, представляющий собой max-кучу. Если
существует несколько решений, выведите любое.
Пример входа |
Пример выхода |
6 5 3 2 7 1 10 |
10 7 5 3 1 2 |
куча
Сохраним входные данные в массив а. Для всех
индексов массива от n / 2 до 1 последовательно применим
процедуру heapify. В
результате массив преобразуется в max-кучу.
Пример
Ниже
приведены исходный массив и конечный массив, являющийся кучей.
Реализация алгоритма
Объявим массив,
который в дальнейшем будет преобразован в кучу.
#define MAX 1001
int a[MAX];
Функция left возвращает индекс левого сына.
int left(int i)
{
return 2 * i;
}
Функция right возвращает индекс правого сына.
int right(int i)
{
return 2 * i + 1;
}
Функция swap меняет местами элементы с индексами i и j.
void swap(int &i, int &j)
{
int temp = i; i = j; j = temp;
}
Функция heapify восстанавливает свойство кучи для поддерева с корнем в
вершине с индексом i. Третий
параметр n задаёт
размер поддерживаемой кучи.
void heapify(int a[], int i, int n)
{
int largest = 0;
int l = left(i);
int r = right(i);
Находим индекс максимального элемента среди текущего
элемента a[i] и его сыновей a[l] и a[r].
if (l <= n && a[l] > a[i]) largest = l;
else largest = i;
if (r <= n && a[r]
> a[largest]) largest = r;
Если a[i] не является максимальным
элементом, меняем его местами с максимальным сыном и далее рекурсивно
восстанавливаем свойство кучи в соответствующем поддереве (левом или правом).
if (largest != i)
{
swap(a[i], a[largest]);
heapify(a, largest,
n);
}
}
Основная часть программы. Читаем входной массив,
начиная с индекса 1.
scanf("%d", &n);
for (i = 1; i <= n; i++)
scanf("%d", &a[i]);
Для всех индексов от n / 2 до 1 последовательно выполним процедуру heapify.
for (i = n / 2; i > 0; i--)
heapify(a, i, n);
Выводим результирующий массив, который представляет
собой max-кучу.
for (i = 1; i <= n; i++)
printf("%d ", a[i]);
printf("\n");
Java реализация
import java.util.*;
public class Main
{
static int left(int i)
{
return 2 * i;
}
static int right(int i)
{
return 2 * i + 1;
}
static void
swap(int a[], int i, int j)
{
int temp = a[i]; a[i] = a[j]; a[j] = temp;
}
//max - heap
static void
heapify(int a[], int i, int n) // n = size of a heap
{
int largest = 0;
int l = left(i);
int r = right(i);
if (l <= n && a[l] > a[i]) largest = l;
else largest = i;
if (r <= n && a[r] > a[largest]) largest = r;
if (largest != i)
{
swap(a, i, largest);
heapify(a, largest, n);
}
}
public static void main(String[] args) {
Scanner con = new Scanner(System.in);
int n = con.nextInt();
int m[] = new int[n+1];
for(int i = 1; i <= n; i++)
m[i] = con.nextInt();
for(int i = n / 2; i > 0; i--)
heapify(m,i,n);
for(int i = 1; i <= n; i++)
System.out.print(m[i] + " ");
System.out.println();
con.close();
}
}