Heap-Sort ist eine vergleichsbasierte Sortierungstechnik, die auf der binären Heap-Datenstruktur basiert. Sie ist ähnlich wie die Auswahlsortierung, bei der wir zuerst das maximale Element finden und dieses an das Ende setzen. Wir wiederholen den gleichen Vorgang für die restlichen Elemente.
Was ist Binary Heap?
Lassen Sie uns zunächst einen vollständigen Binärbaum definieren. Ein vollständiger Binärbaum ist ein Binärbaum, bei dem jede Ebene, außer möglicherweise der letzten, vollständig gefüllt ist und alle Knoten so weit links wie möglich stehen (Quelle Wikipedia)
Ein Binärer Heap ist ein vollständiger Binärbaum, bei dem die Elemente in einer speziellen Reihenfolge gespeichert werden, so dass der Wert in einem Elternknoten größer (oder kleiner) ist als die Werte in seinen beiden Kindknoten. Ersteres wird als Max-Heap und letzteres als Min-Heap bezeichnet. Der Heap kann durch einen binären Baum oder ein Array dargestellt werden.
Warum eine Array-basierte Darstellung für einen binären Heap?
Da ein Binary Heap ein vollständiger Binärbaum ist, kann er leicht als Array dargestellt werden und die Array-basierte Darstellung ist platzsparend. Wenn der Elternknoten bei Index I gespeichert ist, kann das linke Kind durch 2 * I + 1 und das rechte Kind durch 2 * I + 2 berechnet werden (unter der Annahme, dass die Indizierung bei 0 beginnt).
Heap-Sort-Algorithmus zum Sortieren in aufsteigender Reihenfolge:
1. Bilden Sie einen maximalen Heap aus den Eingabedaten.
2. Zu diesem Zeitpunkt ist das größte Element an der Wurzel des Heaps gespeichert. Ersetzen Sie es durch das letzte Element des Heaps und reduzieren Sie anschließend die Größe des Heaps um 1. Zum Schluss heapen Sie die Wurzel des Baums.
3. Wiederholen Sie Schritt 2, solange die Größe des Heaps größer als 1 ist.
Wie wird der Heap aufgebaut?
Die Heapify-Prozedur kann nur dann auf einen Knoten angewendet werden, wenn seine Kinderknoten heapifiziert sind. Die Heapification muss also in der Reihenfolge von unten nach oben durchgeführt werden.
Lassen Sie uns das mit Hilfe eines Beispiels verstehen:
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
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);
}
}
Python
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),
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
Hier ist der vorherige C-Code als Referenz.
Hinweise:
Heap-Sort ist ein In-Place-Algorithmus.
Seine typische Implementierung ist nicht stabil, kann aber stabil gemacht werden (siehe dies)
Zeitkomplexität: Die Zeitkomplexität von heapify ist O(Logn). Die Zeitkomplexität von createAndBuildHeap() ist O(n) und die Gesamtzeitkomplexität von Heap Sort ist O(nLogn).
Anwendungen von HeapSort
1. Sortieren eines fast sortierten (oder K-sortierten) Arrays
2. k größte (oder kleinste) Elemente in einem Array
Der Heap-Sort-Algorithmus ist nur begrenzt einsetzbar, da Quicksort und Mergesort in der Praxis besser sind. Dennoch wird die Heap-Datenstruktur selbst enorm häufig verwendet. Siehe Anwendungen der Heap-Datenstruktur
https://youtu.be/MtQL_ll5KhQ
Snapshots:
Quiz zu Heap Sort
Weitere Sortieralgorithmen auf GeeksforGeeks/GeeksQuiz:
QuickSort, Selection Sort, Bubble Sort, Insertion Sort, Merge Sort, Heap Sort, QuickSort, Radix Sort, Counting Sort, Bucket Sort, ShellSort, Comb Sort, Pigeonhole Sort
Kodierübung zum Sortieren.