HeapSort é uma técnica de classificação baseada numa comparação baseada na estrutura de dados Binary Heap. É semelhante à classificação de selecção onde primeiro encontramos o elemento máximo e colocamos o elemento máximo no final. Repetimos o mesmo processo para os elementos restantes.
O que é o Binary Heap?
Deixe-nos primeiro definir uma Árvore Binária Completa. Uma árvore binária completa é uma árvore binária em que cada nível, excepto possivelmente o último, é completamente preenchido, e todos os nós são o mais à esquerda possível (Fonte Wikipedia)
Uma pilha binária é uma árvore binária completa onde os itens são armazenados numa ordem especial de modo a que o valor num nó pai seja maior (ou menor) do que os valores nos seus dois nós filhos. O primeiro é chamado de pilha máxima e o segundo é chamado de pilha minada. A pilha pode ser representada por uma árvore binária ou array.
Porquê representação baseada em array para o Binary Heap?
Desde que uma pilha binária é uma árvore binária completa, pode ser facilmente representada como um array e a representação baseada em array é eficiente em termos de espaço. Se o nó pai for armazenado no índice I, o filho esquerdo pode ser calculado por 2 * I + 1 e o filho direito por 2 * I + 2 (assumindo que a indexação começa em 0).
Gloritmo de Ordenação do Salto para ordenação em ordem crescente:
1. Construir uma pilha máxima a partir dos dados de entrada.
2. Neste ponto, o maior item é armazenado na raiz da pilha. Substitui-la pelo último item da pilha, seguido da redução do tamanho da pilha por 1. Finalmente, heapificar a raiz da árvore.
3. Repita o passo 2 enquanto o tamanho da pilha é superior a 1.
Como construir a pilha?
O procedimento de heapificação só pode ser aplicado a um nó se os seus nós filhos forem heapificados. Portanto, a heapificação deve ser executada na ordem de baixo para cima.
Vamos compreender com a ajuda de um exemplo:
>br>
Input data: 4, 10, 3, 5, 1 4(0) / \ 10(1) 3(2) / \ 5(3) 1(4)The numbers in bracket represent the indices in the array representation of data.Applying heapify procedure to index 1: 4(0) / \ 10(1) 3(2) / \5(3) 1(4)Applying heapify procedure to index 0: 10(0) / \ 5(1) 3(2) / \ 4(3) 1(4)The heapify procedure calls itself recursively to build heap in top down manner.
#include <iostream>
using
namespace
std;
void
heapify(
int
arr,
int
n,
int
i)
{
int
largest = i;
int
l = 2 * i + 1;
int
r = 2 * i + 2;
if
(l < n && arr > arr)
largest = l;
if
(r < n && arr > arr)
largest = r;
if
(largest != i) {
swap(arr, arr);
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, arr);
heapify(arr, i, 0);
}
}
void
printArray(
int
arr,
int
{
for
(
int
i = 0; i < n; ++i)
cout << arr <<
" "
;
cout <<
"\n"
;
}
int
main()
{
int
arr = { 12, 11, 13, 5, 6, 7 };
int
n =
sizeof
(arr) /
sizeof
(arr);
heapSort(arr, n);
cout <<
"Sorted array is \n"
;
printArray(arr, n);
}
br>
>/p>
>/p>
public
class
HeapSort {
public
void
sort(
int
arr)
{
int
n = arr.length;
for
(
int
i = n /
2
-
1
; i >=
0
; i--)
heapify(arr, n, i);
for
(
int
i = n -
1
; i >
0
; i--) {
int
temp = arr;
arr = arr;
arr = temp;
heapify(arr, i,
0
);
}
void
heapify(
int
arr,
int
n,
int
i)
{
int
largest = i;
int
l =
2
* i +
1
;
int
r =
2
* i +
2
;
if
(l < n && arr > arr)
largest = l;
if
(r < n && arr > arr)
largest = r;
if
(largest != i) {
int
swap = arr;
arr = arr;
arr = swap;
heapify(arr, n, largest);
}
}
static
void
printArray(
int
arr)
{
int
n = arr.length;
for
(
int
i =
0
; i < n; ++i)
System.out.print(arr +
" "
);
System.out.println();
}
public
static
void
main(String args)
{
int
arr = {
12
,
11
,
13
,
5
,
6
,
7
};
int
n = arr.length;
HeapSort ob =
new
HeapSort();
ob.sort(arr);
System.out.println(
"Sorted array is"
);
printArray(arr);
}
}
>br>>>/div>
def
heapify(arr, n, i):
largest
=
i
l
=
2
*
i
+
1
r
=
2
*
i
+
2
if
l < n
and
arr < arr:
largest
=
l
if
r < n
and
arr < arr:
largest
=
r
if
largest !
=
i:
arr, arr
=
arr, arr
heapify(arr, n, largest)
def
heapSort(arr):
n
=
len
(arr)
for
i
in
range
(n
/
/
2
-
1
,
-
1
,
-
1
):
heapify(arr, n, i)
for
i
in
range
(n
-
1
,
0
,
-
1
):
arr, arr
=
arr, arr
heapify(arr, i,
0
)
arr
=
heapSort(arr)
n
=
len
(arr)
print
(
"Sorted array is"
)
for
i
in
range
(n):
print
(
"%d"
%
arr),
>/div>
>br>
br>>
using
System;
public
class
HeapSort {
public
void
sort(
int
arr)
{
int
n = arr.Length;
for
(
int
i = n / 2 - 1; i >= 0; i--)
heapify(arr, n, i);
for
(
int
i = n - 1; i > 0; i--) {
int
temp = arr;
arr = arr;
arr = temp;
heapify(arr, i, 0);
}
void
heapify(
int
arr,
int
n,
int
i)
{
int
largest = i;
int
l = 2 * i + 1;
int
r = 2 * i + 2;
if
(l < n && arr > arr)
largest = l;
if
(r < n && arr > arr)
largest = r;
if
(largest != i) {
int
swap = arr;
arr = arr;
arr = swap;
heapify(arr, n, largest);
}
}
static
void
printArray(
int
arr)
{
int
n = arr.Length;
for
(
int
i = 0; i < n; ++i)
Console.Write(arr +
" "
);
Console.Read();
}
public
static
void
Main()
{
int
arr = { 12, 11, 13, 5, 6, 7 };
int
n = arr.Length;
HeapSort ob =
new
HeapSort();
ob.sort(arr);
Console.WriteLine(
"Sorted array is"
);
printArray(arr);
}
}
<?php
function
heapify(&
$arr
,
$n
,
$i
)
{
$largest
=
$i
;
$l
= 2*
$i
+ 1;
$r
= 2*
$i
+ 2;
if
(
$l
<
$n
&&
$arr
>
$arr
)
$largest
=
$l
;
if
(
$r
<
$n
&&
$arr
>
$arr
)
$largest
=
$r
;
if
(
$largest
!=
$i
)
{
$swap
=
$arr
;
$arr
=
$arr
;
$arr
=
$swap
;
heapify(
$arr
,
$n
,
$largest
);
}
}
function
heapSort(&
$arr
,
$n
)
{
for
(
$i
=
$n
/ 2 - 1;
$i
>= 0;
$i
--)
heapify(
$arr
,
$n
,
$i
);
for
(
$i
=
$n
-1;
$i
> 0;
$i
--)
{
$temp
=
$arr
;
$arr
=
$arr
;
$arr
=
$temp
;
heapify(
$arr
,
$i
, 0);
}
}
function
printArray(&
$arr
,
$n
)
{
for
(
$i
= 0;
$i
<
$n
; ++
$i
)
echo
(
$arr
.
" "
) ;
}
$arr
=
array
(12, 11, 13, 5, 6, 7);
$n
= sizeof(
$arr
)/sizeof(
$arr
);
heapSort(
$arr
,
$n
);
echo
'Sorted array is '
.
"\n"
;
printArray(
$arr
,
$n
);
?>
Sorted array is 5 6 7 11 12 13
Aqui está o código C anterior para referência.
Notas:
Amostras é um algoritmo no local.
A implementação típica não é estável, mas pode ser tornada estável (Ver isto)
Complexidade temporal: A complexidade temporal do heapify é O(Logn). A complexidade temporal de createAndBuildHeap() é O(n) e a complexidade temporal global de Heap Sort é O(nLogn).
Aplicações de HeapSort
1. Ordenar um conjunto quase ordenado (ou K ordenado)
2. k maiores (ou menores) elementos de um conjunto
O algoritmo de ordenação Heap tem utilizações limitadas porque o Quicksort e o Mergesort são melhores na prática. No entanto, a própria estrutura de dados Heap é enormemente utilizada. Ver Aplicações da Estrutura de Dados Heap
https://youtu.be/MtQL_ll5KhQbr>Snapshots:
br>
Quiz em Heap Sort
Outros Algoritmos de Triagem em GeeksforGeeks/GeeksQuiz:
QuickSortar, Selecção, Bolha, Inserção, Misturar, Sortido, Sortido, QuickSort, Sortido de Radix, Sortido de Contagem, Sortido de Balde, Sortido de Conchas, Sortido de Pombos, Sortido de Pombos, Sortido de Pombos
P>Prática de codificação para triagem.