Algoritmul de sortare în heap (cu Code in Python și C++)

⚡ Rezumat inteligent

Algoritmul de sortare prin heap sortează o matrice prin construirea unui heap binar și exprimarea repetată a acestuia.tracintroducerea valorii sale rădăcină în secțiunea sortată. Această resursă explică heapify, heap-urile max și min, pseudo-codul și completarea Python și C++ implementări cu analiză de complexitate temporală.

  • 🌳 Ideea de bază: Sortarea în heap construiește o heap binară completă, apoi exprimă în mod repetattracts rădăcina pentru a produce o ordine sortată.
  • 🔺 Îngrămădire: Operația heapify restaurează proprietatea heap prin swapping un părinte cu copilul său mai mare.
  • 🗃️ Stocare matriceală: O memorie heap este stocată într-un tablou în care un nod la indexul i are copii la 2i+1 și 2i+2.
  • ⏱️ Complexitate: Sortarea în heap se execută în timp O(n log n) în toate cazurile și utilizează O(1) spațiu suplimentar.
  • 💻 Code Furnizat: De lucru Python și C++ programele demonstrează heapify, construirea heap-ului și sortarea completă.

Ce este algoritmul Heap Sort?

Sortarea în heap este unul dintre algoritmii de sortare populari și mai rapizi. Este construit pe structura completă a datelor arborelui binar. Vom căuta elementul maxim și îl vom plasa în vârf pentru heap-ul maxim. Îl vom plasa pe nodul părinte al arborelui binar.

Să presupunem că este dat o matrice, date = [10,5, 7, 9, 4, 11, 45, 17, 60].

În tablou, dacă indicele i-al (i=0,1,2,3 …) este un nod părinte, atunci (2i+1) și (2i+2) vor fi copiii din stânga și din dreapta. Crearea unui arbore binar complet cu această matrice va arăta astfel:

Algoritmul Heap Sort

Vom face procesul de heapify de la începutul până la sfârșitul matricei. Inițial, dacă convertim tabloul într-un arbore, acesta va arăta ca cel de mai sus. Putem vedea că nu menține nicio proprietate heap (min-heap sau max heap). Vom obține matricea sortată făcând procesul heapify pentru toate nodurile.

Aplicarea Heap Sort

Iată câteva modalități de utilizare a algoritmului de sortare heap:

  • Construcția „Cozilor prioritare” necesită sortare în grămada. Deoarece heapsort menține elementul sortat după fiecare inserare.
  • Heap Data Structure este eficientă în găsirea kth cel mai mare element dintr-o matrice dată.
  • Linux Kernel folosește sortarea heap ca implicită algoritm de sortare deoarece are O (1) complexitate spațială.

Creați sortare heap cu exemplu

Aici, vom construi un heap maxim din următorul arbore binar complet.

Creați sortare heap cu exemplu

Nodurile frunzelor sunt 17, 60, 4, 11 și 45. Nu au niciun nod copil. De aceea sunt noduri de frunze. Deci, vom începe metoda heapify de la nodul lor părinte. Iată pașii:

Pas 1) Selectați sub-arborele din stânga. Dacă nodurile copil sunt mai mari, schimbați nodul părinte cu nodul copil.

Aici nodul părinte este 9. Iar nodurile secundare sunt 17 și 60. Deoarece 60 este cel mai mare, 60 și 9 vor fi schimbate pentru a menține heap max.

Creați sortare heap cu exemplu

Pas 2) Acum, subarborele din stânga este îngrămădit. Următorul nod părinte este 7. Acest părinte are două noduri copil, iar cel mai mare este 45. Deci, 45 și 7 vor fi schimbate.

Creați sortare heap cu exemplu

Creați sortare heap cu exemplu

Pas 3) Nodurile 60 și 4 au nodul părinte 5. Deoarece „5” este mai mic decât nodul copil 60, acesta va fi schimbat.

Creați sortare heap cu exemplu

Creați sortare heap cu exemplu

Pas 4) Acum, nodul 5 are nodul copil 17,9. Aceasta nu menține proprietatea maxim heap. Deci, 5 va fi înlocuit cu 17.

Creați sortare heap cu exemplu

Pas 5) Nodul 10 va fi schimbat cu 60, apoi schimbat cu 17. Procesul va arăta ca următorul.

Creați sortare heap cu exemplu

Creați sortare heap cu exemplu

Pas 6) Până la pasul 5, am creat heap-ul maxim. Fiecare nod părinte este mai mare decât nodurile sale secundare. Nodul rădăcină are valoarea maximă (60).

Notă: Pentru a crea matricea sortată, trebuie să înlocuim nodul cu valoarea maximă cu succesorul său.

Acest proces se numește „extractmax”. Deoarece 60 este nodul maxim, îi vom fixa poziția la indexul 0 și vom crea heap-ul fără nodul 60.

Creați sortare heap cu exemplu

Creați sortare heap cu exemplu

Pas 7) Pe măsură ce se elimină 60, următoarea valoare maximă este 45. Vom face procesul „Extract Max” din nou din nodul 45.

De data aceasta vom obține 45 și vom înlocui nodul rădăcină cu succesorul său 17.

Trebuie să facem "Extract Max” până când toate elementele sunt sortate.

După ce am parcurs acești pași până când am extracCu toate valorile maxime, vom obține următorul array.

Creați sortare heap cu exemplu

Ce este Binary Heap?

Un morman binar este un fel de complet arbore binar structură de date. În acest tip de structură arborescentă, nodul părinte este fie mai mare, fie mai mic decât nodurile secundare. Dacă nodul părinte este mai mic, atunci heap-ul se numește „Min Heap” și dacă nodul părinte este mai mare, heap-ul se numește „Max Heap”.

Iată exemple de heap min și heap maxim.

Min Heap și Max Heap
Min Heap și Max Heap

În figura de mai sus, dacă observați „Min Heap”, nodul părinte este întotdeauna mai mic decât nodurile sale secundare. În capul copacului, putem găsi cea mai mică valoare 10.

În mod similar, pentru „Max Heap”, nodul părinte este întotdeauna mai mare decât nodurile secundare. Elementul maxim este prezent la nodul principal pentru „Max Heap”.

Ce este „Heapify”?

„Heapify” este principiul heap-ului care asigură poziția nodului. În Heapify, un heap maxim menține întotdeauna o relație cu părintele și copilul, și acesta este nodul părinte va fi mai mare decât nodurile copil.

De exemplu, dacă se adaugă un nod nou, trebuie să remodelăm heap-ul. Cu toate acestea, este posibil să fie nevoie să modificăm sau să interschimbăm nodurile sau să rearanjăm matricea. Acest proces de remodelareping o heap se numește „heapify”.

Iată un exemplu despre cum funcționează heapify:

Adăugarea unui nou nod și Heapify
Adăugarea unui nou nod și heapify

Iată pașii pentru heapify:

Pas 1) S-a adăugat nodul 65 ca fiul drept al nodului 60.

Pas 2) Verificați dacă nodul adăugat nou este mai mare decât cel părinte.

Pas 3) Deoarece este mai mare decât nodul părinte, am schimbat copilul potrivit cu părintele său.

Cum se construiește Heap

Înainte de a construi grămada sau de a îngrămădi un copac, trebuie să știm cum îl vom depozita. Deoarece grămada este un arbore binar complet, este mai bine să utilizați un mulțime pentru a păstra datele mormanului.

Să presupunem că o matrice conține un total de n elemente. Dacă indicele „i” este un nod părinte, atunci nodul din stânga va fi la index (2i+1), iar nodul din dreapta va fi la index (2i+2). Presupunem că indexul matricei începe de la 0.

Folosind aceasta, haideți să stocăm un heap maxim într-o matrice care urmează:

Reprezentarea bazată pe matrice a heap-ului maxim
Reprezentare bazată pe matrice a heap-ului maxim

Algoritmul heapify menține proprietatea heap. Dacă părintele nu are valoarea extremă (mai mică sau mai mare), aceasta va fi schimbată cu nodul copil cel mai extrem.

Iată pașii pentru a acumula un heap maxim:

Pas 1) Începeți de la nodul frunzei.

Pas 2) Găsiți maximul dintre părinte și copii.

Pas 3) Schimbați nodurile dacă nodul copil are o valoare mai mare decât cel părinte.

Pas 4) Urcă cu un nivel.

Pas 5) Urmați pașii 2,3,4 până ajungem la indicele 0 sau sortăm întregul arbore.

Iată pseudo-codul pentru heapify recursiv (heap maxim):

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)

Pseudo Code pentru sortare în grămadă

Iată pseudo-codul pentru algoritmul de sortare heap:

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)

Exemplu de sortare în heap 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);
}

ieșire:

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

Exemplu de sortare în heap 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)

ieșire:

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

Analiza complexității în timp și spațiu a sortării heap

Există complexitatea timpului și complexitatea spațiului pe care le putem analiza pentru sortarea grămezilor. Pentru complexitatea timpului avem următoarele cazuri:

  1. Cel mai bun caz
  2. Caz mediu
  3. Cel mai rău caz

Heap-ul este implementat pe un arbore binar complet. Deci, la nivelul de jos al arborelui binar, va exista numărul maxim de noduri. Dacă nivelul inferior are n noduri, atunci nivelul de mai sus va avea n/2 noduri.

Analiza complexității în timp și spațiu

În acest exemplu, Nivelul 3 are patru articole, nivelul 2 are două elemente, iar nivelul 1 are un articol. Dacă există un număr total de n articole, înălțimea sau nivelul total va fi Log2(n). Deci, inserarea unui singur element ar putea dura un maxim de iterații Log(n).

Când vrem să luăm valoarea maximă din heap, luăm doar nodul rădăcină. Apoi, din nou, rulați heapify. Fiecare heapify ia Log2(N) timp. Ex.tracAtingerea maximului durează O(1).

Cea mai bună complexitate a timpului de caz pentru algoritmul de sortare heap

Când toate elementele sunt deja sortate în matrice, va dura O(n) timp pentru a construi heap-ul. Pentru că dacă lista este sortată, atunci inserarea unui element va dura timpul constant care este O(1).

Deci, va dura O(n) timp pentru a crea un max-heap sau min-heap în cel mai bun caz.

Complexitatea medie a timpului de caz pentru algoritmul de sortare heap

Introducerea unui element sau a unui exemplutracAtingerea unui maxim costă O(log(n)) timp. Deci, complexitatea medie a timpului de caz pentru algoritmul de sortare heap este O(n log(n)).

Complexitatea timpului cel mai rău caz pentru algoritmul de sortare heap

Similar cu cazul mediu, în cel mai rău scenariu, s-ar putea să efectuăm heapify de n ori. Fiecare heapify va costa O(log(n)) timp. Deci, cel mai rău caz de complexitate va fi O(n log(n)).

Complexitatea spațială pentru algoritmul de sortare în grămada

Sortarea grămadă este un algoritm proiectat în loc. Aceasta înseamnă că nu este necesară nicio memorie suplimentară sau temporară pentru a efectua sarcina. Dacă vedem implementarea, vom observa că am folosit swap () pentru a efectua schimbul de noduri. Nu a fost nevoie de altă listă sau matrice. Deci, complexitatea spațiului este O(1).

Întrebări frecvente

Sortarea în heap nu este un algoritm de sortare stabil, deoarece construirea și extracExtragerea elementelor din heap poate reordona elementele egale. Dacă păstrarea ordinii originale a cheilor egale este importantă, un algoritm stabil, cum ar fi sortarea prin îmbinare, este o alegere mai bună.

Sortarea heap garantează un timp O(n log n) în toate cazurile și utilizează O(1) spațiu suplimentar. Sortarea rapidă este de obicei mai rapidă în practică, dar poate degrada la O(n²) în cazul pivoturilor greșite. Sortarea heap schimbă o parte din viteză pentru un caz cel mai rău fiabil.

Atât sortarea heap, cât și sortarea merge se execută într-un timp de O(n log n). Sortarea heap sortează în loc cu O(1) spațiu suplimentar, dar este instabilă. Sortarea merge este stabilă, dar necesită O(n) spațiu suplimentar pentru mergere.

Tutorii cu inteligență artificială pot anima procesul de heapify, pot arăta cum se formează heap-ul maxim și tracfiecare extracPasul t-max. Acest ajutor vizual și interactiv facilitează înțelegerea de către începători a modului în care sortează o matrice prin sortare heap.

Da. Asistenții de codare cu inteligență artificială pot traduce o implementare de sortare heap între limbaje precum C++, Python și Java în timp ce keeping logica intactă. Ar trebui să compilați și să testați în continuare codul convertit pentru a confirma rezultatul corect.

Rezumați această postare cu: