Table of Contents

Laborator 06 - Liste generice

Responsabili:

Obiective

În urma parcurgerii acestui laborator studentul va fi capabil:

Liste

O listă este o instanţă a unui tip de date abstract ce formalizează conceptul de colecţie ordonată de entităţi. În mod minimal, o listă este caracterizată prin:

Cum se implementează?

Pentru implementarea listelor, există două modalităţi de bază: folosind liste înlănţuite (simplu sau dublu înlănţuite) sau folosind array-uri dinamice.

Tipuri de liste înlănţuite

Listă liniară simplu înlănţuită

Are o singură legatură la fiecare nod. Această legatură indică întotdeauna următorul nod din listă, sau o valoare nulă (dacă suntem la finalul listei), sau o listă liberă (pentru identificarea ei).

Listă liniară dublu-înlănţuită

Fiecare nod din listă liniara dublu înlănţuită are două legături:

Listă circulară simplu-înlănţuită

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).

Fiecare nod are o 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 o 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.

Listă circulară dublu înlănţuită

list.h
template <typename T>
struct Node {
    T value;
    Node<T> *next, *prev;
    Node (T value) {
	this->value = value;
        next = prev = NULL;
    }
    Node() {
        next = prev = NULL; 
    }
};
 
template <typename T>
class LinkedList {
private:
    Node<T> *pFirst, *pLast;
public: 
    // Constructor
    LinkedList();
    // Destructor
    ~LinkedList();
 
    /* Adauga un nod cu valoarea == value la inceputul listei. */
    void addFirst(T value);
 
    /* Adauga un nod cu valoarea == value la sfarsitul listei. */
    void addLast(T value);
 
    /* Elimina elementul de la inceputul listei si intoarce valoarea acestuia. */
    T removeFirst();
 
    /* Elimina elementul de la sfarsitul listei listei si intoarce valoarea acestuia. */
    T removeLast();
 
    /* Elimina prima aparitie a elementului care are valoarea == value. */
    T removeFirstOccurrence(T value);
 
    /* Elimina ultima aparitie a elementului care are valoarea == value. */
    T removeLastOccurrence(T value);
 
    /* Afiseaza elementele listei pe o singura linie, separate printr-un spatiu. */
    void printList();
 
    /* Intoarce true daca lista este vida, false altfel. */
    bool isEmpty();
};
 
#endif

Exerciții

1) [5p] Implementați în header-ul definit anterior funcțiile pentru o listă liniară dublu înlănțuită.

2) [2p] Implementați o stivă folosind liste.

stack.h
#ifndef __STACK__H
#define __STACK__H
 
template<typename T>
class Stack {
public:
    // Constructor
    Stack();
 
    // Destructor
    ~Stack();
 
    void push(T x);
    T pop();
    T peek();
    int isEmpty();
 
private:
    // Vectorul de stocare.
    LinkedList<T> stackList;
    // De ce nu mai este nevoie sa retinem topLevel?
};
#endif

3) [2p] Implementați o coadă folosind liste.

queue.h
#ifndef __QUEUE_H
#define __QUEUE_H
 
template <typename T>
class Queue {
private:
    // De ce nu mai este nevoie sa retinem head, tail si size?
    LinkedList<T> queueList;
 
public:
    // Constructor.
    Queue();
 
    // Destructor.
    ~Queue();
 
    void enqueue(T e);
    T dequeue();
    T front();
    int isEmpty();
};
 
#endif

BONUS [bragging rights] Implementati inversarea unei liste simplu inlantuite, fara memorie auxiliara.

Interviu

Această secțiune nu este punctată și încearcă să vă facă o oarecare idee a tipurilor de întrebări pe care le puteți întâlni la un job interview (internship, part-time, full-time, etc.) din materia prezentată în cadrul laboratorului.

1. Scrieti un program care sa afizeseze elementul din mijlocul unei liste fara a folosi un contor si fara a sti dimensiunea listei.

2. Scrieti un program care se detecteze o bucla intr-o lista simplu inlantuita.

3. Scrieți o funcție care inversează o listă simplu înlănțuită fără a folosi memorie auxiliară.

Resurse

[1] C++ Reference

[2] Linked List Queue Visualization

[3] Linked List Stack Visualziation

[4] List C++