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 13:52] georgem [Leftist Heap] |
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 53: | Line 66: | ||
| Acestă operație se numește: ''sift-down'', ''percolate-down'', ''cascade-down'', ... | Acestă operație se numește: ''sift-down'', ''percolate-down'', ''cascade-down'', ... | ||
| + | |||
| 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 66: | Line 81: | ||
| Un ''delete'' se implementează prin eliminarea ''root-ului'' și apelarea funcției de ''merge'' pe copilul stâng și cel drept. | Un ''delete'' se implementează prin eliminarea ''root-ului'' și apelarea funcției de ''merge'' pe copilul stâng și cel drept. | ||
| + | |||
| + | [[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 158: | 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> | + | |
| ===== Recommended Reading ===== | ===== Recommended Reading ===== | ||