Differences

This shows you the differences between two versions of the page.

Link to this comparison view

sd-ca:laboratoare:lab-02 [2020/03/15 21:44]
andrei.vasiliu2211 [Exerciții]
sd-ca:laboratoare:lab-02 [2024/03/12 10:29] (current)
maria.sfiraiala [Laborator 2 - Liste înlănțuite]
Line 3: Line 3:
 Responsabili Responsabili
  
-  * [[mailto:amirea99@gmail.com|Adrian Mirea]] +  * [[mailto:andreipirlea03@gmail.com|Andrei Pîrlea]] 
-  * [[mailto:alexcosmin.mihai@gmail.com|Alexandru Mihai]]+  * [[mailto:stef.dascalu@gmail.com|Ștefan-Teodor Dascălu]]
  
  
Line 24: Line 24:
 ===== LinkedList ===== ===== LinkedList =====
  
-O listă înlănțuită (LinkedList) reprezintă o structură de date liniară și omogenă. Spre deosebire de vector, lista înlănțuită nu își are elementele într-o zonă contiguă de memorie ci fiecare element (nod al listei) va conține pe langă informația utilă și legătură către nodul următor (listă simplu înlănțuită),​ sau legături către nodurile vecine (listă dublu înlănțuită). Alocând dinamic nodurile pe măsură ce este nevoie de ele, practic se pot obține liste de lungime limitată doar de cantitatea de memorie accesibilă programului.+O listă înlănțuită (LinkedList) reprezintă o structură de date liniară și omogenă. Spre deosebire de vector, lista înlănțuită nu își are elementele într-o zonă contiguă de memorieci fiecare element (nod al listei) va conține pe langă informația utilă și legătură către nodul următor (listă simplu înlănțuită),​ sau legături către nodurile vecine (listă dublu înlănțuită). Alocând dinamic nodurile pe măsură ce este nevoie de ele, practic se pot obține liste de lungime limitată doar de cantitatea de memorie accesibilă programului.
  
 <note important>​ <note important>​
Line 48: Line 48:
  
 Asupra unei liste înlănțuite ar trebui să putem executa urmatoarele operații: Asupra unei liste înlănțuite ar trebui să putem executa urmatoarele operații:
-  * ''<​nowiki>​void add_nth_node(struct LinkedList* list, int n, void* new_data);</​nowiki>''​ adaugă pe poziția n în listă elementul ''​new_data''​. Adăugarea presupune modificarea câmpului ''​next''​ al nodului în urma căruia se va adăuga noul nod, cât și a câmpului ''​next''​ al nodului adăugat pentru a face legăturile necesare ca lista sa funcționeze corect. Dacă nodul este adăugat pe prima poziție, atunci el va deveni ''​head''​-ul listei, iar dacă este adăugat pe ultima poziție, el va deveni ''​tail''​-ul listei. //​Complexitate:​ ''​O(n)''​. Dacă se adaugă elementul în capul sau coada listei, se obține o complexitate mai buna: ''​O(1)''​.//​+  * ''<​nowiki>​void add_nth_node(struct LinkedList* list, int n, void* new_data);</​nowiki>''​ adaugă pe poziția n în listă elementul ''​new_data''​. Adăugarea presupune modificarea câmpului ''​next''​ al nodului în urma căruia se va adăuga noul nod, cât și a câmpului ''​next''​ al nodului adăugat pentru a face legăturile necesare ca lista sa funcționeze corect. Dacă nodul este adăugat pe prima poziție, atunci el va deveni ''​head''​-ul listei, iar dacă este adăugat pe ultima poziție, el va deveni ''​tail''​-ul listei. //​Complexitate:​ ''​O(n)''​. Dacă se adaugă elementul în capul sau coada listei, se obține o complexitate mai bună: ''​O(1)''​.//​
  
-  * ''<​nowiki>​struct Node* remove_nth_node(struct LinkedList* list, int n);</​nowiki>''​ șterge și întoarce al ''​n''​-lea element al listei. Operația presupune modificarea listei astfel încât între nodurile vecine celui eliminat să se refacă legaturile pentru a permite listei ​sa funcționeze în continuare. Daca nu există un nod următor, ''​head''​ va deveni NULL, iar lista va fi goală. Dacă nodul eliminat era ''​head-ul''​ listei, atunci succesorul său îi va lua locul. Analog pentru ultimul nod, însă în această situație, nodul precedent devine ''​tail''​. //​Complexitate:​ ''​O(n)''​. Dacă se șterge primul nod, se obține o complexitate mai buna: ''​O(1)''​. Aceeași complexitate se obține și dacă lista este dublu înlănțuită și se șterge ultimul nod.//+  * ''<​nowiki>​struct Node* remove_nth_node(struct LinkedList* list, int n);</​nowiki>''​ șterge și întoarce al ''​n''​-lea element al listei. Operația presupune modificarea listei astfel încât între nodurile vecine celui eliminat să se refacă legaturile pentru a permite listei ​să funcționeze în continuare. Daca nu există un nod următor, ''​head''​ va deveni NULL, iar lista va fi goală. Dacă nodul eliminat era ''​head-ul''​ listei, atunci succesorul său îi va lua locul. Analog pentru ultimul nod, însă în această situație, nodul precedent devine ''​tail''​. **Atentie!** Funcția doar returnează nodul eliminat din listă, deci rămâne de datoria voastră să eliberați memoria ocupată de nodul obținut în urma apelului funcției. //​Complexitate:​ ''​O(n)''​. Dacă se șterge primul nod, se obține o complexitate mai bună: ''​O(1)''​. Aceeași complexitate se obține și dacă lista este dublu înlănțuită și se șterge ultimul nod.//
  
   * ''<​nowiki>​int get_size(struct LinkedList* list);</​nowiki>''​ întoarce numărul curent de elemente stocate în listă. //​Complexitate:​ ''​O(1)''//​   * ''<​nowiki>​int get_size(struct LinkedList* list);</​nowiki>''​ întoarce numărul curent de elemente stocate în listă. //​Complexitate:​ ''​O(1)''//​
Line 85: Line 85:
 {{:​sd-ca:​playground:​lista_simplu_inlantuita.png?​direct|}} {{:​sd-ca:​playground:​lista_simplu_inlantuita.png?​direct|}}
  
-===== Schelet ===== +<note important>​ 
- +O schemă folositoare pentru a înțelege mai bine scheletul de laborator și listele se află în următorul document: 
-{{:​sd-ca:​laboratoare:​schelet_lab02_linkedlist.zip|}} +{{:​sd-ca:​laboratoare:​lab2-linked-list.pdf|}}
-===== Exerciții ===== +
-<​note>​ +
-Fiecare laborator va avea unul sau doua exerciții publice și un pool de subiecte ascunse, din care asistentul poate alege cum se formeaza celelalte puncte ale laboratorului.+
 </​note>​ </​note>​
  
-[**5p**] Implementaţi,​ plecând de la scheletul de cod, lista liniară simplu înlănțuită.+==== Listă circulară simplu-înlănţuită ====
  
-**311CAa**+Primul şi ultimul nod sunt legate împreună. Pentru a parcurge o listă circular înlănţuită se începe de la oricare nod şi se urmăreşte lista prin aceasta direcţie aleasă până când se ajunge la nodul de unde s-a pornit parcurgerea (lucru valabil şi pentru listele circulare dublu-înlănţuite).
  
-[**2p**] Implementați ​funcție care primește ca parametru un pointer la începutul unei liste simplu înlănțuite și inversează ordinea nodurilor din listă (fără alocare ​de memorie auxiliară pentru ​nouă listă).+Fiecare nod are singură legatură, similar cu listele liniare ​simplu-înlănţuite, însă, diferenţa constă în legătura aflată după ultimul nod ce îl leagă pe acesta ​de primul nod. La fel ca şi în listele liniare simplu-înlănţuite,​ nodurile noi pot fi inserate eficient numai dacă acestea se află după un nod care are referinţe la acesta. Din acest motiv, este necesar să se menţină numai referinţă către ultimul element dintr-o ​listă ​circulară simplu-înlănţuita,​ căci aceasta permite o inserţie rapidă la nodul de început al listei, şi de asemenea, permite accesul la primul nod prin legatura dintre acesta şi ultimul nod.
  
-//Exemplu//pentru lista //1 → 2 → 3// rezultă lista //3 → 2 → 1//.+{{sd-ca:playground:​lista_circ_simplu.png?​direct&​ |}}
  
-**311CAb** 
  
-[**2p**] Implementați o funcție care primește ca parametri doi pointeri la începuturile a două liste simplu înlănțuite sortate și întoarce o listă simplu înlănțuită sortată ce conține toate elementele din cele două liste. 
  
-//​Exemplu//:​ pentru listele //1 → 2 → 5 → 9// și  //2 → 3 → 7 → 8 → 10// rezultă lista //1 → 2 → 2 → 3 → 5 → 7 → 8 → 9 → 10//.+===== Exerciții =====
  
-**312CAa** +<​note>​ 
- +Trebuie ​să vă creați cont de [[https://lambdachecker.io | Lambda Checker]], dacă nu v-ați creat dejape care îl veți folosi la SD pe toată durata semestrului. 
-[**2p**] Implementați o funcție care primește ca parametri un pointer la începutul unei liste simplu înlănțuite și șterge elementul aflat în mijlocul listei. Ștergerea trebuie ​să se facă printr-o singură parcurgere a listei. +</​note>​
- +
-//​Exemple//:​ +
-  * pentru lista //vidă//, rezultă lista //​vidă//;​ +
-  * pentru lista //1//, rezultă lista //​vidă//;​ +
-  * pentru lista //1 → 2//, rezultă lista //2//; +
-  * pentru lista //1 → 2 → 3//, rezultă lista //1 → 3//; +
-  * pentru lista //1 → 2 → 3 → 4//, rezultă lista //1 → 3 → 4//; +
-  * pentru lista //1 → 2 → 3 → 4 → 5//, rezultă lista //1 → 2 → 4 → 5//. +
- +
-**312CAb** +
- +
-[**2p**] Implementați o funcție care primește ca parametri un pointer la începutul unei liste simplu înlănțuite și un element și adaugă elementul în mijlocul listei. Adăugarea trebuie să se facă printr-o singură parcurgere a listei. +
- +
-//Exemple// (elementul adăugat este X): +
-  * pentru lista //vidă//, rezultă lista //X//; +
-  * pentru lista //1//, rezultă lista //X → 1//; +
-  * pentru lista //1 → 2//, rezultă lista //1 → X → 2//; +
-  * pentru lista //1 → 2 → 3//, rezultă lista //1 → X → 2 → 3//; +
-  * pentru lista //1 → 2 → 3 → 4//, rezultă lista //1 → 2 → X → 3 → 4//; +
-  * pentru lista //1 → 2 → 3 → 4 → 5//, rezultă lista //1 → 2 → X → 3 → 4 → 5//. +
-**313CAa** +
- +
-[**2p**] Implementați o funcție care primește ca parametru un pointer la începutul unei liste simplu înlănțuite și construiește două liste în care se vor afla toate elementele ​de pe poziții pare, respectiv impare, în aceeași ordine. +
- +
-//​Exemplu//:​ pentru lista //1 → 2 → 2 → 3 → 5 → 7 → 8 → 9//, rezultă listele //1 → 2 →  5 → 8// și //2 → 3 → 7 → 9//. +
- +
- +
-**313CAb** +
- +
-[**2p**] Fiind date două liste simplu înlănțuite cu numar egal de elemente, contopiți-le astfel încât după fiecare nod provenit dintr-o listă să urmeze un nod din cealaltă listă. Nu alocați noduri noi! +
- +
-//​Exemplu//:​ pentru listele //1 → 3 → 5// și //2 → 4 → 6//, rezultă lista //1 → 2 → 3 → 4 → 5 → 6//. +
- +
-**314CAa** +
- +
-[**2p**] Se dă o listă simplu înlănțuită ale cărei noduri rețin valori de tip int și, se dă de asemenea, un integer X. Reordonați nodurile din listă astfel încât toate nodurile cu valori mai mici sau egale decât X să apară înaintea nodurilor cu valori mai mari decât X. Nu alocați noduri noi! +
- +
-//Exemplu//pentru lista //3 → 6 → 5 → 4 → 2// și integer-ul //3//, o posibilă listă rezultat este //2 → 4 → 3 → 6 → 5//. +
- +
- +
-**314CAb** +
- +
-[**2p**Fiind date două liste simplu înlănțuite,​ A și B, ale căror noduri stochează valori integer, construiți o nouă listă simplu înlănțuită,​ C, pentru care fiecare nod i este suma nodurilor asociate din A și B. Mai exact, nodul i din C reține suma dintre valoarea nodului i din A și valoarea nodului i din B. Dacă una dintre listele primite este mai lungă decât cealaltă, se consideră că nodurile asociate lipsă din cealaltă listă conțin valoarea 0, adică se păstrează valorile din lista mai lungă. +
- +
-//​Exemplu//:​ pentru listele //A: 3 → 7 → 29 → 4// și //B: 2 → 4 → 3//, va rezulta lista //C: 5 → 11 → 32 → 4//. +
- +
- +
- +
-**315CAa** +
- +
-[**2p**Se dau două liste simplu înlănțuiteA și B, ale căror noduri stochează în ordine inversă cifrele câte unui număr natural reprezentat în baza 10 (primul nod al unei liste stochează cea mai puțin semnificativă cifră). Creați o nouă listă simplu înlănțuită,​ C, care stochează suma celor două numere. Lista C trebuie construită în timp ce se parcurg listele A și B! +
- +
-//​Exemplu//:​ pentru listele //A: 4 → 3 → 2 → 9// și //B: 6 → 6 → 7//, rezultă lista //C: 0 → 0 → 0 → 0 → 1//. +
- +
- +
- +
-**315CAb** +
- +
-[**2p**] Se dă o listă simplu înlănțuită ale cărei noduri stochează câte un caracter. Verificați dacă șirul de caractere stocat de lista simplu înlănțuită reprezintă un palindrom. Puteți folosi ​o nouă listă auxiliară sau puteți modifica lista primită, dar nu puteți să rețineți șirul în afara unei liste (de ex. nu aveți voie să parcurgeți lista și să stocați șirul ​la o adresă la care pointează un char*).+
  
-//Exemplu//pentru lista //l → u → p → u → l//, rezultă ​ca este palindrom.+{{:sd-ca:​laboratoare:​lab_2:​lab02_skel_2024.zip|Scheletul de laborator}}
  
 +Enunțurile problemelor le găsiți pe Lambda Checker, [[https://​beta.lambdachecker.io/​contest/​68/​problems?​page=1| aici]].
 +Tot acolo veți și încărca soluțiile voastre.
  
 ===== Interviu ===== ===== Interviu =====
sd-ca/laboratoare/lab-02.1584301440.txt.gz · Last modified: 2020/03/15 21:44 by andrei.vasiliu2211
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0