Le tri Heap est une technique de tri par comparaison basée sur la structure de données Binary Heap. Il est similaire au tri de sélection où nous trouvons d’abord l’élément maximum et le plaçons à la fin. Nous répétons le même processus pour les éléments restants.
Qu’est-ce que le tas binaire ?
Définissons d’abord un arbre binaire complet. Un arbre binaire complet est un arbre binaire dans lequel chaque niveau, sauf éventuellement le dernier, est complètement rempli, et tous les nœuds sont le plus à gauche possible (Source Wikipédia)
Un tas binaire est un arbre binaire complet où les éléments sont stockés dans un ordre particulier tel que la valeur d’un nœud parent est supérieure(ou inférieure) aux valeurs de ses deux nœuds enfants. Le premier est appelé max-heap et le second min-heap. Le tas peut être représenté par un arbre binaire ou un tableau.
Pourquoi une représentation basée sur un tableau pour le tas binaire ?
Puisqu’un Binary Heap est un arbre binaire complet, il peut être facilement représenté comme un tableau et la représentation basée sur un tableau est efficace en termes d’espace. Si le nœud parent est stocké à l’indice I, l’enfant gauche peut être calculé par 2 * I + 1 et l’enfant droit par 2 * I + 2 (en supposant que l’indexation commence à 0).
Algorithme de tri de tas pour le tri en ordre croissant :
1. Construire un tas max à partir des données d’entrée.
2. A ce stade, le plus grand élément est stocké à la racine du tas. Remplacez-le par le dernier élément du tas suivi de la réduction de la taille du tas par 1. Enfin, heapifier la racine de l’arbre.
3. répéter l’étape 2 tant que la taille du tas est supérieure à 1.
Comment construire le tas ?
La procédure Heapify ne peut être appliquée à un nœud que si ses nœuds enfants sont heapifiés. Donc l’heapification doit être effectuée dans l’ordre ascendant.
Permettons de comprendre à l’aide d’un exemple :
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>
std;
void
heapify(
int
arr,
int
n,
int
i)
.. {
int
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
n)
{
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);
}
.
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);
}
}
.
def
heapify(arr, n, i):
largest
=
i
l
=
2
*
i
+
1
.
r
=
2
+
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
,
-
iv 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
(n):
print
(
"%d"
%
arr),
using
System;
public
class
HeapSort {
public
void
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
Voici le code C précédent pour référence.
Notes :
Le tri heap est un algorithme in-place.
Sa mise en œuvre typique n’est pas stable, mais peut être rendue stable (Voir ceci)
Complexité temporelle : La complexité temporelle de heapify est O(Logn). La complexité temporelle de createAndBuildHeap() est O(n) et la complexité temporelle globale de Heap Sort est O(nLogn).
Applications de HeapSort
1. Trier un tableau presque trié (ou K trié)
2. k plus grands (ou plus petits) éléments dans un tableau
L’algorithme de tri Heap a des utilisations limitées car Quicksort et Mergesort sont meilleurs en pratique. Néanmoins, la structure de données Heap elle-même est énormément utilisée. Voir Applications de la structure de données Heap
https://youtu.be/MtQL_ll5KhQ
Snapshots :
.
Quiz sur Heap Sort
Autres algorithmes de tri sur GeeksforGeeks/GeeksQuiz :
Tri rapide, tri sélectif, tri à bulles, tri par insertion, tri par fusion, tri par tas, tri rapide, tri radix, tri par comptage, tri par seau, tri par coquille, tri par peigne, tri par pigeonnier
Pratique de codage pour le tri.