Table of Contents

Exercitiul 1

Metoda Agregatelor

ArrayList - inserare

Raspuns: ĉi = 3

Explicatie: Incepem cu un array cu capacitate 1 si 0 elemente (vom nota cost insert = ci, copiere n elemente = cpyn.

Observam ca numarul de copieri este cpy1 + cpy2 + cpy4 + cpy8 + … + cpyn = 2 * n (suma geometrica). (1)

De asemenea, au avut loc n insert-uri, care au c = n. (2)

Din (1) si (2) ⇒ ĉi = T(n) / n = (2 * n + n) / n = 3.

ArrayList - stergere

Raspuns = ĉi = 2.

Presupunem cel mai rau caz: capacitate = 4 * n, nr. elemente = n + 1 (delete va cauza o copiere, deoarece la primul delete ajungem la 1/4 din capacitate)

Observam ca numarul de copieri este cpyn/2 + cpyn/4 + cpyn/8 + … = n. (1)

Numarul de stergeri efective este n. (2)

Din (1) si (2) ⇒ ĉi = T(n) / n = (n + n) / n = 2.

ArrayList - cazul generic

Fie capacitatea initiala = 1, ci = costul inserarii, cd = costul stergerii.

Stim ca:

⇒ ĉi = Ctotal / (k + p) = (Cins + Cdel) / (k + p)

Am stabilit precedent ca:

De asemenea:

⇒ ĉi = (3k + 2p) / (k + p)

Interpretare:

Metoda bancherului

(pentru insertion: 3 bani → 1 inserare, 1 banut atribuit inseratiei curente, 1 banut atribuit altei inseratii din bucata copiata precedent)

Idee de rezolvare: impartim array-ul in 2 bucati:

Pentru fiecare operatie de stergere (cost 1), “plasam” un banut catre prima bucata a array-ului (cea care se va copia). In acest fel, la momentul copierii, fiecare element are deja banutul pregatit care ii acopera costul. Astfel, nu mai trebuit platit un cost suplimentar pentru copiere.

Metoda potentialelor

ĉi = ci + Φ(Di) - Φ(Di-1).

Definim n = elemente curente, m = capacitate:

Fie

  Φ(n,m) = 2n - m,  daca n >= m/2
         = m/2 - n, altfel

1. Cazul stergerii in cazul in care capacitatea nu se schimba:

Aflam ca pentru un load factor de peste 1/2 (suntem aproape de capacitatea maxima) avem cost amortizat -1, iar 2 daca ne apropiem de injumatatire.

In operatiile de analiza amortizata, noi luam drept cost amortizat costul operatiilor mai “scumpe”, neluand in calcul operatiile “ieftine”, deci ĉi = 2 in acest caz, nu -1.

2. Cazul stergerii in care capacitatea se schimba:

Algebraic Data Types

1.

typedef struct list {
    int e;
    struct list *next;
} *List;

List Void() {
    return NULL;
}

List Cons(int e, List list) {
    List newElem = (List)malloc(sizeof(struct list));
    newElem->e = e;
    newElem->next = list;

    return newElem;
}

2.

Size(Void) = 0
Size(Cons(e, L)) = 1 + Size(L)
Add(Void, x) = Cons(x, Void)
Add(Cons(y, L), x) = Cons(y, Add(L, x)
Append(Void, L) = L
Append(Cons(x, L1), L2) = Cons(x, Append(L1, L2))
Reverse(Void) = Void
Reverse(Cons(x, L)) = Append(Reverse(L), Cons(x, Void))

Helper:

isNull(Void) = True
isNull(Cons(x, L)) = False

3.

bool isNull(List l) {
    return l == NULL;
}

int size(List l) {
    if (isNull(l))
        return 0;
    return 1 + size(l->next);
}

List add(List l, int x) {
    if isNull(l))
        return Cons(x, Void());
    return Cons(l->e, add(l->next, x));
}

List append(List l1, List l2) {
    if (isNull(l1))
        return l2;
    return Cons(l1->e, append(l1->next, l2));
}

List reverse(List l) {
    if (isNull(l))
        return Void();
    return append(reverse(l->next), Cons(l->e, Void()));
}