Heap-Sort-Algorithmus (mit Code in Python und C++)

โšก Intelligente Zusammenfassung

Der Heap-Sort-Algorithmus sortiert ein Array, indem er einen binรคren Heap erstellt und diesen wiederholt durchlรคuft.tracDer Wurzelwert wird in den sortierten Bereich eingefรผgt. Diese Ressource erklรคrt Heapify, Max- und Min-Heaps, Pseudocode und die vollstรคndige Implementierung. Python und C++ Implementierungen mit Zeitkomplexitรคtsanalyse.

  • ๐ŸŒณ Kernidee: Heapsort erstellt einen vollstรคndigen binรคren Heap und fรผhrt diesen dann wiederholt aus.tracts ist die Wurzel, um eine sortierte Reihenfolge zu erzeugen.
  • ๐Ÿ”บ Heapify: Die Operation heapify stellt die Heap-Eigenschaften durch Swap wieder her.ping ein Elternteil mit seinem grรถรŸeren Kind.
  • ๐Ÿ—ƒ๏ธ Array-Speicher: Ein Heap wird in einem Array gespeichert, wobei ein Knoten am Index i Kinder an den Positionen 2i+1 und 2i+2 hat.
  • ๏ธ Komplexitรคt: Der Heapsort hat in allen Fรคllen eine Laufzeit von O(n log n) und benรถtigt O(1) zusรคtzlichen Speicherplatz.
  • ๐Ÿ’ป Code Unter der Voraussetzung: Zusammen Arbeiten Python und C++ Die Programme demonstrieren Heapify, Heap-Aufbau und die vollstรคndige Sortierung.

Was ist ein Heap-Sortieralgorithmus?

Heapsort ist einer der beliebtesten und schnellsten Sortieralgorithmen. Er basiert auf der Datenstruktur eines vollstรคndigen Binรคrbaums. Wir suchen das grรถรŸte Element und fรผgen es oben im Heap, dem Elternknoten des Binรคrbaums, ein.

Nehmen wir an, ein Array sei gegeben, Daten = [10,5, 7, 9, 4, 11, 45, 17, 60].

Wenn im Array der i-te Index (i=0,1,2,3 โ€ฆ) ein รผbergeordneter Knoten ist, sind (2i+1) und (2i+2) die linken und rechten untergeordneten Knoten. Das Erstellen eines vollstรคndigen Binรคrbaums mit diesem Array sieht folgendermaรŸen aus:

Heap-Sortieralgorithmus

Wir fรผhren den Heapify-Prozess vom Anfang bis zum Ende des Arrays durch. Wenn wir das Array zunรคchst in einen Baum umwandeln, sieht es wie oben aus. Wir kรถnnen sehen, dass es keine Heap-Eigenschaft (Min-Heap oder Max-Heap) beibehรคlt. Wir erhalten das sortierte Array, indem wir den Heapify-Prozess fรผr alle Knoten durchfรผhren.

Anwendung der Heap-Sortierung

Hier ist eine Verwendung des Heap-Sortieralgorithmus:

  • Der Aufbau von โ€žPrioritรคtswarteschlangenโ€œ erfordert eine Heap-Sortierung. Weil Heapsort das Element nach jedem Einfรผgen sortiert hรคlt.
  • Die Heap-Datenstruktur ist effizient beim Finden des kth grรถรŸtes Element in einem bestimmten Array.
  • Der Linux-Kernel verwendet standardmรครŸig die Heap-Sortierung Sortieralgorithmus da es eine Speicherkomplexitรคt von O (1) hat.

Erstellen Sie eine Heap-Sortierung anhand eines Beispiels

Hier werden wir einen maximalen Heap aus dem folgenden vollstรคndigen Binรคrbaum konstruieren.

Erstellen Sie eine Heap-Sortierung anhand eines Beispiels

Die Blattknoten sind 17, 60, 4, 11 und 45. Sie haben keine untergeordneten Knoten. Deshalb sind sie Blattknoten. Daher starten wir die Heapify-Methode von ihrem รผbergeordneten Knoten aus. Hier sind die Schritte:

Schritt 1) Wรคhlen Sie den Unterbaum ganz links aus. Wenn die untergeordneten Knoten grรถรŸer sind, tauschen Sie den รผbergeordneten Knoten mit dem untergeordneten Knoten aus.

Hier ist der รผbergeordnete Knoten 9. Und die untergeordneten Knoten sind 17 und 60. Da 60 der grรถรŸte ist, werden 60 und 9 vertauscht, um die beizubehalten max Haufen.

Erstellen Sie eine Heap-Sortierung anhand eines Beispiels

Schritt 2) Jetzt wird der am weitesten links stehende Teilbaum gehรคuft. Der nรคchste รผbergeordnete Knoten ist 7. Dieser รผbergeordnete Knoten hat zwei untergeordnete Knoten, und der grรถรŸte ist 45. Daher werden 45 und 7 vertauscht.

Erstellen Sie eine Heap-Sortierung anhand eines Beispiels

Erstellen Sie eine Heap-Sortierung anhand eines Beispiels

Schritt 3) Die Knoten 60 und 4 haben den รผbergeordneten Knoten 5. Da โ€ž5โ€œ kleiner als der untergeordnete Knoten 60 ist, wird er vertauscht.

Erstellen Sie eine Heap-Sortierung anhand eines Beispiels

Erstellen Sie eine Heap-Sortierung anhand eines Beispiels

Schritt 4) Jetzt hat Knoten 5 den untergeordneten Knoten 17,9. Dadurch wird die Max-Heap-Eigenschaft nicht beibehalten. Also wird 5 durch 17 ersetzt.

Erstellen Sie eine Heap-Sortierung anhand eines Beispiels

Schritt 5) Knoten 10 wird mit 60 und dann mit 17 ausgetauscht. Der Vorgang sieht wie folgt aus.

Erstellen Sie eine Heap-Sortierung anhand eines Beispiels

Erstellen Sie eine Heap-Sortierung anhand eines Beispiels

Schritt 6) Bis Schritt 5 haben wir den maximalen Heap erstellt. Jeder รผbergeordnete Knoten ist grรถรŸer als seine untergeordneten Knoten. Der Wurzelknoten hat den Maximalwert (60).

Hinweis: Um das sortierte Array zu erstellen, mรผssen wir den Knoten mit dem hรถchsten Wert durch seinen Nachfolger ersetzen.

Dieser Vorgang heiรŸt โ€žextract maxโ€œ. Da 60 der maximale Knoten ist, legen wir seine Position auf den 0. Index fest und erstellen den Heap ohne Knoten 60.

Erstellen Sie eine Heap-Sortierung anhand eines Beispiels

Erstellen Sie eine Heap-Sortierung anhand eines Beispiels

Schritt 7) Wenn 60 entfernt wird, ist der nรคchste Maximalwert 45. Wir werden den Prozess โ€žExโ€œ durchfรผhren.tract Maxโ€œ erneut von Knoten 45.

Diesmal erhalten wir 45 und ersetzen den Wurzelknoten durch seinen Nachfolger 17.

Wir mรผssen Leistung erbringenโ€œExtract Maxโ€ bis alle Elemente sortiert sind.

Nachdem wir diese Schritte bis zum Ende durchgefรผhrt habentracDurch die Addition aller Maximalwerte erhalten wir das folgende Array.

Erstellen Sie eine Heap-Sortierung anhand eines Beispiels

Was ist ein binรคrer Heap?

Ein binรคrer Heap ist eine Art vollstรคndiger binรคrer Baum Datenstruktur. In einer solchen Baumstruktur ist der รผbergeordnete Knoten entweder grรถรŸer oder kleiner als die untergeordneten Knoten. Wenn der รผbergeordnete Knoten kleiner ist, wird der Heap โ€žMin Heapโ€œ genannt, und wenn der รผbergeordnete Knoten grรถรŸer ist, wird der Heap โ€žMax Heapโ€œ genannt.

Hier sind Beispiele fรผr Min Heap und Max Heap.

Min. Heap und Max. Heap
Min. Heap und Max. Heap

Wenn Sie in der obigen Abbildung den โ€žMin Heapโ€œ bemerken, ist der รผbergeordnete Knoten immer kleiner als seine untergeordneten Knoten. An der Spitze des Baumes finden wir den kleinsten Wert 10.

Ebenso ist beim โ€žMax Heapโ€œ der รผbergeordnete Knoten immer grรถรŸer als die untergeordneten Knoten. Das maximale Element ist am Kopfknoten fรผr den โ€žMax Heapโ€œ vorhanden.

Was ist โ€žHeapifyโ€œ?

โ€žHeapifyโ€œ ist das Prinzip des Heaps, das die Position des Knotens sicherstellt. Bei Heapify behรคlt ein Max-Heap immer eine Beziehung zwischen รผbergeordnetem und untergeordnetem Knoten bei, d. h. der รผbergeordnete Knoten ist grรถรŸer als die untergeordneten Knoten.

Wird beispielsweise ein neuer Knoten hinzugefรผgt, muss der Heap umgeformt werden. Dabei kann es jedoch erforderlich sein, Knoten zu รคndern oder zu vertauschen oder das Array neu anzuordnen. Dieser Umformungsprozessping Ein solcher Haufen wird als โ€žHeapifyโ€œ bezeichnet.

Hier ist ein Beispiel, wie Heapify funktioniert:

Hinzufรผgen eines neuen Knotens und Heapify
Hinzufรผgen eines neuen Knotens und Heapify

Hier sind die Schritte fรผr Heapify:

Schritt 1) Knoten 65 als rechtes untergeordnetes Element von Knoten 60 hinzugefรผgt.

Schritt 2) รœberprรผfen Sie, ob der neu hinzugefรผgte Knoten grรถรŸer als der รผbergeordnete Knoten ist.

Schritt 3) Da er grรถรŸer als der รผbergeordnete Knoten ist, haben wir den rechten untergeordneten Knoten mit seinem รผbergeordneten Knoten vertauscht.

So erstellen Sie den Heap

Bevor wir den Heap erstellen oder einen Baum heapifizieren, mรผssen wir wissen, wie wir ihn speichern werden. Da der Heap ein vollstรคndiger binรคrer Baum ist, ist es besser, einen Array um die Daten des Heaps zu speichern.

Nehmen wir an, ein Array enthรคlt insgesamt n Elemente. Wenn der โ€žiโ€œ-te Index ein รผbergeordneter Knoten ist, befindet sich der linke Knoten am Index (2i+1), und der rechte Knoten befindet sich am Index (2i+2). Wir gehen davon aus, dass der Array-Index bei 0 beginnt.

Lassen Sie uns damit einen maximalen Heap in einem Array wie folgt speichern:

Array-basierte Darstellung des Max Heap
Arraybasierte Darstellung des maximalen Heaps

Der Heapify-Algorithmus behรคlt die Heap-Eigenschaft bei. Wenn der รผbergeordnete Knoten nicht den Extremwert (kleiner oder grรถรŸer) hat, wird er mit dem extremsten untergeordneten Knoten ausgetauscht.

So heben Sie einen maximalen Heap auf:

Schritt 1) Beginnen Sie am Blattknoten.

Schritt 2) Finden Sie das Maximum zwischen Eltern und Kindern.

Schritt 3) Tauschen Sie die Knoten aus, wenn der untergeordnete Knoten einen grรถรŸeren Wert hat als der รผbergeordnete.

Schritt 4) Gehen Sie eine Ebene hรถher.

Schritt 5) Befolgen Sie die Schritte 2,3,4, bis wir den Index 0 erreichen, oder sortieren Sie den gesamten Baum.

Hier ist der Pseudocode fรผr rekursives Heapify (max heap):

def heapify():
  inputโ†’ array, size, i
  largest = i
  left = 2*i + 1
  right = 2*i + 2
if left<n and array[largest ] < array[left]:
  largest = left
if right<n and array[largest ] < array[right]:
  largest = right
If largest not equals i:
  swap(array[i],array[largest])
  heapify(array,n,largest)

Spitzname Code fรผr Heapsort

Hier ist der Pseudocode fรผr den Heap-Sortieralgorithmus:

Heapify(numbers as an array, n as integer, i as integer):
  largest = i
  left = 2i+1
  right= 2i+2
if(left<=n) and (numbers[i]<numbers[left])
  largest=left
if(right<=n) and (numbers[i]<numbers[right])
  largest=right
if(largest  != i)
  swap(numbers[i], numbers[largest])
  Heapify(numbers,n,largest)
HeapSort(numbers as an array):
  n= numbers.size()
for i in range n/2 to 1
  Heapify(numbers,n,i)
for i in range n to 2
  Swap numbers[i] with numbers[1]
  Heapify(numbers,i,0)

Beispiel fรผr Heapsortierung Code in C++

#include <iostream>
using namespace std;
void display(int arr[], int n)
{
    for (int i = 0; i < n; i++)
    {
        cout << arr[i] << "\t";
    }
    cout << endl;
}
void heapify(int numbers[], int n, int i)
{
    int largest = i;
    int left = 2 * i + 1;
    int right = 2 * i + 2;
    if (left < n && numbers[left] < numbers[largest])
    {
        largest = left;
    }
    if (right < n && numbers[right] < numbers[largest])
    {
        largest = right;
    }
    if (largest != i)
    {
	//uncomment the following line to see details in output
        //cout<<"Swapping "<< numbers[i]<< " and "<<numbers[largest]<<endl;
        swap(numbers[i], numbers[largest]);
        heapify(numbers, n, largest);
    }
}
void heapSort(int numbers[], int n)
{
    for (int i = n/2 - 1; i >= 0; i--)
    {
        heapify(numbers, n, i);
//uncomment the following line to see details in output
 //cout<<"Heapify:\t";
  //display(numbers,n);
    }
    for (int i = n - 1; i >= 0; i--)
    {
        swap(numbers[0], numbers[i]);
        heapify(numbers, i, 0);
    }
}
int main()
{
    int numbers[] = { 10,5, 7, 9, 4, 11, 45, 17, 60};
    int size = sizeof(numbers) / sizeof(numbers[0]);
    cout<<"Initial Array:\t";
    display(numbers,size);
    heapSort(numbers, size);
    cout<<"Sorted Array (descending order):\t";
    display(numbers, size);
}

Ausgang:

Initial Array:  10      5       7       9       4       11      45      17      60
Sorted Array (descending order):  60      45      17      11      10      9       7       5       4

Beispiel fรผr Heapsortierung Code in Python

def display(arr):
    for i in range(len(arr)):
    print(arr[i], end = "\t")
print()
def heapify(numbers, n, i):
    largest = i
left = 2 * i + 1
right = 2 * i + 2
if left < n and numbers[left] < numbers[largest]:
    largest = left
if right < n and numbers[right] < numbers[largest]:
    largest = right
if largest != i:
    numbers[i], numbers[largest] = numbers[largest], numbers[i]
heapify(numbers, n, largest)
def heapSort(items, n):
    for i in range(n //2,-1,-1):
        heapify(items, n, i) for i in range(n - 1, -1, -1):
        items[0], items[i] = items[i], items[0] heapify(items, i, 0) numbers = [10, 5, 7, 9, 4, 11, 45, 17, 60] print("Initial List:\t", end = "") display(numbers) print("After HeapSort:\t", end = "") heapSort(numbers, len(numbers)) display(numbers)

Ausgang:

Initial List:   10      5       7       9       4       11      45      17      60
After HeapSort: 60      45      17      11      10      9       7       5       4

Zeitliche und rรคumliche Komplexitรคtsanalyse von Heap Sort

Es gibt Zeitkomplexitรคt und Raumkomplexitรคt, die wir fรผr die Heapsortierung analysieren kรถnnen. Fรผr die Zeitkomplexitรคt gibt es die folgenden Fรคlle:

  1. besten Case
  2. Durchschnittlicher Fall
  3. Schlimmsten Fall

Der Heap wird auf einem vollstรคndigen Binรคrbaum implementiert. Auf der untersten Ebene des Binรคrbaums befindet sich also die maximale Anzahl an Knoten. Wenn die unterste Ebene n Knoten hat, dann hat die obere Ebene n/2 Knoten.

Zeit- und Raumkomplexitรคtsanalyse

In diesem Beispiel verfรผgt Ebene 3 รผber vier Elemente, Ebene 2 รผber zwei Elemente und Ebene 1 รผber ein Element. Wenn insgesamt n Elemente vorhanden sind, wird die Hรถhe bzw. das Gesamtniveau angegeben Log2(N). Das Einfรผgen eines einzelnen Elements kรถnnte also maximal Log(n)-Iterationen erfordern.

Wenn wir den maximalen Wert aus dem Heap nehmen wollen, nehmen wir einfach den Stammknoten. Dann fรผhren wir erneut das Heapify aus. Jedes Heapify nimmt Log2(n) Zeit. BeispieltracDas Erreichen des Maximums benรถtigt O(1) Zeit.

Bester Fall der Zeitkomplexitรคt fรผr den Heapsort-Algorithmus

Wenn alle Elemente bereits im Array sortiert sind, dauert der Aufbau des Heaps O(n) Zeit. Denn wenn die Liste sortiert ist, dauert das Einfรผgen eines Elements die konstante Zeit O(1).

Daher wird es im besten Fall O(n) Zeit dauern, einen Max-Heap oder Min-Heap zu erstellen.

Durchschnittliche Fallzeitkomplexitรคt fรผr den Heapsort-Algorithmus

Einfรผgen eines Elements oder BeispielstracDas Finden eines Maximums kostet O(log(n)) Zeit. Die durchschnittliche Zeitkomplexitรคt des Heapsort-Algorithmus betrรคgt also O(n log(n)).

Worst-Case-Zeitkomplexitรคt fรผr den Heapsort-Algorithmus

ร„hnlich wie im durchschnittlichen Fall mรผssen wir im schlimmsten Fall Heapify n-mal durchfรผhren. Jedes Heapify kostet O(log(n)) Zeit. Die Zeitkomplexitรคt im schlimmsten Fall betrรคgt also O(n log(n)).

Speicherkomplexitรคt fรผr den Heapsort-Algorithmus

Heapsort ist ein direkt entwickelter Algorithmus. Das bedeutet, dass kein zusรคtzlicher oder temporรคrer Speicher benรถtigt wird, um die Aufgabe auszufรผhren. Wenn wir uns die Implementierung ansehen, werden wir feststellen, dass wir swap() verwendet haben, um den Austausch der Knoten durchzufรผhren. Es wurde keine andere Liste oder kein anderes Array benรถtigt. Die Speicherkomplexitรคt betrรคgt also O(1).

Hรคufig gestellte Fragen

Heapsort ist kein stabiler Sortieralgorithmus, da der Aufbau und die Exponenten nicht stabil sind.tracDurch das Entfernen von Elementen aus dem Heap kรถnnen gleiche Elemente neu angeordnet werden. Wenn die Beibehaltung der ursprรผnglichen Reihenfolge gleicher Schlรผssel wichtig ist, ist ein stabiler Algorithmus wie Mergesort die bessere Wahl.

Heapsort garantiert in allen Fรคllen eine Laufzeit von O(n log n) und benรถtigt O(1) zusรคtzlichen Speicherplatz. Quicksort ist in der Praxis meist schneller, kann aber bei ungรผnstigen Pivotelementen auf O(nยฒ) abfallen. Heapsort bietet im Gegenzug fรผr eine zuverlรคssige Worst-Case-Lรถsung einen geringeren Zeitaufwand.

Sowohl Heapsort als auch Mergesort haben eine Laufzeit von O(n log n). Heapsort sortiert direkt im Speicher mit O(1) zusรคtzlichem Speicherplatz, ist aber instabil. Mergesort ist stabil, benรถtigt aber O(n) zusรคtzlichen Speicherplatz zum Zusammenfรผhren.

KI-Tutoren kรถnnen den Heapify-Prozess animieren und zeigen, wie der Max-Heap entsteht, und trace jedes Beispieltract-max Schritt. Diese visuelle, interaktive Hilfe erleichtert Anfรคngern das Verstรคndnis, wie Heapsort ein Array sortiert.

Ja. KI-Programmierassistenten kรถnnen eine Heapsort-Implementierung zwischen Sprachen wie โ€ฆ รผbersetzen. C++, Python und Java wรคhrend keeping Die Logik bleibt erhalten. Sie sollten den konvertierten Code dennoch kompilieren und testen, um die korrekte Ausgabe zu bestรคtigen.

Fassen Sie diesen Beitrag mit folgenden Worten zusammen: