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.
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.
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:
(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.
ĉ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.
2. Cazul stergerii in care capacitatea se schimba:
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()));
}