Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
pp:lheap [2019/04/01 14:29] dmihai [Exerciții] |
pp:lheap [2019/04/18 14:23] (current) georgem [Exerciții] |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== TODO ====== | + | ====== Structuri funcționale de date ====== |
Scopul laboratorului: | Scopul laboratorului: | ||
* recapitularea conceptelor învățate | * recapitularea conceptelor învățate | ||
- | * programarea cu o structură funcțională | + | * programarea cu o structură de date funcțională |
* înțelegerea conceptului de "leftist heap" | * înțelegerea conceptului de "leftist heap" | ||
Line 17: | Line 17: | ||
* ''top'' - returnează elementul cu prioritatea maximă | * ''top'' - returnează elementul cu prioritatea maximă | ||
* ''delete'' - scoate elementul cu prioritatea maximă din coadă | * ''delete'' - scoate elementul cu prioritatea maximă din coadă | ||
+ | |||
+ | O altă operație utilă (și necesară în unele implementări) este ''merge'', care primește două liste de priorități și le combină într-una singură. | ||
Coada de priorități este o structură abstractă, ce poate avea diverse implementări care diferă prin complexitatea diverselor operații (e.g. ''insert'', ''delete''). | Coada de priorități este o structură abstractă, ce poate avea diverse implementări care diferă prin complexitatea diverselor operații (e.g. ''insert'', ''delete''). | ||
Line 22: | Line 24: | ||
Un exemplu naiv este implementarea unei cozi de priorități folosind o listă. Avem două posibilități: să introducem complexitatea determinării priorității în funcția ''top'', sau în ''insert''. | Un exemplu naiv este implementarea unei cozi de priorități folosind o listă. Avem două posibilități: să introducem complexitatea determinării priorității în funcția ''top'', sau în ''insert''. | ||
- | Putem pune mereu un element la începutul listei (astfel ''insert'' e echivalent cu '':''). Atunci când avem nevoie de cel cu prioritatea cea mai mare, pornim o căutare liniară prin elementele listei. Similar pentru ștergere. Avem astfel complexitățile: | + | Putem pune mereu un element la începutul listei (astfel ''insert'' e echivalent cu '':''). Atunci când avem nevoie de cel cu prioritatea cea mai mare, pornim o căutare liniară prin elementele listei. Similar pentru ștergere. Pentru operația de ''merge'' putem folosi append din Haskell (''%%+%%%%+%%''). Avem astfel complexitățile: |
| Funcție | Complexitate | | | Funcție | Complexitate | | ||
Line 29: | Line 31: | ||
| ''top'' | ''O(n)'' | | | ''top'' | ''O(n)'' | | ||
| ''delete'' | ''O(n)'' | | | ''delete'' | ''O(n)'' | | ||
+ | | ''merge'' | ''O(n)'' | | ||
+ | |||
+ | <note> | ||
+ | ''n'' este lungimea listei care stă la baza cozii. Pentru ''merge'', ''n'' este lungimea listei din stânga. | ||
+ | </note> | ||
- | Alternativ, simplificând funcția ''top'', ne asigurăm că elementele sunt mereu //ordonate// în listă (astfel, ''top'' este echivalent cu ''head''). Inserarea unui element într-o listă ordonată se face în timp liniar. Avem astfel complexitățile: | + | Alternativ, simplificând funcția ''top'', ne asigurăm că elementele sunt mereu //ordonate// în listă (astfel, ''top'' este echivalent cu ''head''). Inserarea unui element într-o listă ordonată se face în timp liniar (amintiți-vă de //insert sort//). Combinarea a două liste ordonate se face, deasemena în timp liniar (amintiți-vă de //merge sort//). Avem astfel complexitățile: |
| Funcție | Complexitate | | | Funcție | Complexitate | | ||
Line 37: | Line 44: | ||
| ''top'' | ''O(1)'' | | | ''top'' | ''O(1)'' | | ||
| ''delete'' | ''O(1)'' | | | ''delete'' | ''O(1)'' | | ||
+ | | ''merge'' | ''O(n+m)'' | | ||
+ | |||
+ | <note> | ||
+ | Pentru ''merge'', considerăm două liste cu dimensiunile ''n'', respectiv ''m''. | ||
+ | </note> | ||
Implementarea cu liste nu este ideală și putem obține performanțe mai bune. | Implementarea cu liste nu este ideală și putem obține performanțe mai bune. | ||
+ | |||
==== Binary Heap ==== | ==== Binary Heap ==== | ||
Line 55: | Line 68: | ||
Se poate observa că aceste operații ar fi greu de implementat într-un stil funcțional. | Se poate observa că aceste operații ar fi greu de implementat într-un stil funcțional. | ||
+ | |||
==== Leftist Heap === | ==== Leftist Heap === | ||
Line 69: | Line 83: | ||
[[https://courses.cs.washington.edu/courses/cse326/08sp/lectures/markup/05-leftist-heaps-markup.pdf | Leftist heap - more info ]] | [[https://courses.cs.washington.edu/courses/cse326/08sp/lectures/markup/05-leftist-heaps-markup.pdf | Leftist heap - more info ]] | ||
+ | |||
+ | Obținem complexitățile: | ||
+ | |||
+ | | Funcție | Complexitate | | ||
+ | | ''isEmpty'' | ''O(1)'' | | ||
+ | | ''insert'' | ''O(log(n))'' | | ||
+ | | ''top'' | ''O(1)'' | | ||
+ | | ''delete'' | ''O(log(n))'' | | ||
+ | | ''merge'' | ''O(log(n))'' | | ||
+ | |||
===== newtype ===== | ===== newtype ===== | ||
Line 161: | Line 185: | ||
- Folosiți arbori binari pentru a implementa un leftist heap | - Folosiți arbori binari pentru a implementa un leftist heap | ||
- | <note tip> | + | {{:pp:laborator_6_-_schelet.zip|Lab 6 - Schelet}}\\ |
- | Clasa ''PQueue'' conține unele funcții cu implementări default. Considerați înlocuirea acestora cu implementări particularizate. | + | |
- | </note> | + | |
- | {{:pp:laboratorul_6_-_schelet.zip|Lab 6 - Schelet}} | ||
===== Recommended Reading ===== | ===== Recommended Reading ===== | ||