Download as pdf or txt
Download as pdf or txt
You are on page 1of 25

Algorytmy i Struktury Danych

(wykªad 005 - Structures)

Edward Szczypka

04 listopada 2022

1 / 24
Podstawowe struktury danych: STOS
Dozwolone operacje
top(S) - pobranie warto±ci elementu z góry stosu,
pop(S) - ±ci¡gni¦cie elementu ze stosu,
push(S, x) - wªo»enie elementu na stos,
empty(S) - sprawdzenie czy stos jest pusty.
Podstawowe Implementacje
tablicowa,
listowa,

2 / 24
Podstawowe struktury danych: LISTA
Lista L = [x1 , . . . xn ]
Dozwolone operacje
▶ dost¦p do elementu L[i] = xi ,
▶ podlista L[i, .., j] = [xi , xi+1 , . . . , xj ],
▶ zªo»enie dla K = [y1 , . . . ym ], mamy L&K = [x1 , . . . , xn , y1 , . . . , ym ].
Te operacje wystarczaj¡ do deniowania innych, np wstawianie elementu
x na miejsce i, mo»na zdeniowa¢ jako x[1, .., xi ]&[x]&[xi+1 , .., xn ].
Zwyczajowe u»ycie list:
f ront(L) L[1],
push(L, x) L = [x]&L,
pop(L) L = L[2..|L|],
rear(L) L[|L|],
set(L, i, x) L[i] = x,
get(L, i) L[i],
add(L, i, x) L = L[1, . . . , i − 1]&[x]&L[i, . . . , |L|],
remove(L, i) L = L[1, . . . , i − 1]&L[i + 1, . . . , |L|],
eject(L) L = L[1, .., |L| − 1],
empty(L) L = [].
3 / 24
Podstawowe struktury danych: LISTA
Mo»liwe implementacje
tablicowa (cykliczna),
linkowana (ró»ne warianty).
za pomoc¡ drzew (binarnych)

4 / 24
Podstawowe struktury danych: LISTA
Implementacja tablicowa listy:
Zª. ±red. Zª. pesym.
Operacja Dziaªanie
poj. operacji poj. operacji
f ront(L) L[1] O(1) O(1),
push(L, x) L = [x]&L O(1) lub O(n) O(1) lub O(n)
pop(L) L = L[2..|L|] O(1) lub O(n) O(1) lub O(n)
rear(L) L[|L|] O(1) O(1),
set(L, i, x) L[i] = x O(1) O(1),
get(L, i) L[i] O(1) O(1)
L = L[1, . . . , i − 1]
add(L, i, x) O(n) O(n)
&[x]&L[i, . . . , |L|]
L = L[1, . . . , i − 1]
remove(L, i) O(n) O(n)
&L[i + 1, . . . , |L|]
eject(L) L = L[1, .., |L| − 1] O(1) lub O(n) O(1) lub O(n)
empty(L) L = [] O(1) O(1).

5 / 24
Podstawowe struktury danych: LISTA
Implementacja listy za pomoc¡ listy linkowanej:
Zª. ±red. Zª. pesym.
Operacja Dziaªanie
poj. operacji poj. operacji
f ront(L) L[1] O(1) O(1),
push(L, x) L = [x]&L O(1) O(1)
pop(L) L = L[2..|L|] O(1) O(1)
rear(L) L[|L|] O(1) lub O(n) O(1) lub O(n),
set(L, i, x) L[i] = x O(n) O(n),
get(L, i) L[i] O(n) O(n)
L = L[1, . . . , i − 1]
add(L, i, x) O(n) O(n)
&[x]&L[i, . . . , |L|]
L = L[1, . . . , i − 1]
remove(L, i) O(n) O(n)
&L[i + 1, . . . , |L|]
eject(L) L = L[1, .., |L| − 1] O(1) lub O(n) O(1) lub O(n)
empty(L) L = [] O(n) O(n).

6 / 24
Podstawowe struktury danych: LISTA (SkipLista)
Implementacja listy za pomoc¡ skiplisty:
L3 +5 31 +∞ +∞

L2 +3 17 +2 31 53 +∞ +∞

L1 +2 15 17 +2 31 53 +2 61 +∞

L0 11 15 17 28 31 53 56 61 +∞

Im mniejszy numer listy tym mniejsza ilo±¢ przepuszczonych elementów,


Elementy x doªaczamy do kolejnych list L1 , . . . , lk , a» do momentu gdy w
rzucie ucziw¡ monet¡ nie wyjdzie reszka (gdy wypada orzeª doª¡czamy do
kolejnej listy, gdy reszka ko«czymy rozpatrywanie elementu x),

7 / 24
Podstawowe struktury danych: LISTA (SkipLista)
Implementacja listy za pomoc¡ skiplisty:

Wykonanie operacji get(L, 7)


L3 +5 31 +∞ +∞

L2 +3 17 +2 31 53 +∞ +∞

L1 +2 15 17 +2 31 53 +2 61 +∞

L0 11 15 17 28 31 53 56 61 +∞

Startujemy z Listy L3 ,
1 Poniewa» mamy znale¹¢ 7 element a lista L3 pozwala na przeskoczenie 5
elementów to dzi¦ki li±cie L3 przechodzimy do elementu 31 na pozycji 5
2 Poniewa» nast¦ny skok w li±cie L3 ma warto±¢ +∞, to schodimy w dóª do
listy L2 ,
3 Lista L2 daje mozliwo±¢ przej±cia o jeden krok do elementu 53 na miejscu
6,
4 Nast¦pny skok w li±cie L2 to +∞ wi¦c przechodzimy w dóª do listy L1 ,
5 Lista L1 ma skok o dªugo±ci 2, a tutaj jestpotzrebny skok o 1, zatem
idziemy w doª do listy L0 ,
6 Lista L0 ma skok o dªugo±ci 1, do elementu 56 na pozycji 7.
8 / 24
Podstawowe struktury danych: LISTA
Implementacja listy za pomoc¡ skiplisty:

Wykonanie operacji add(L, 7, 55)


L3 +5 31 +2 55 +∞ +∞

L2 +3 17 +2 31 53 55 +∞ +∞

L1 +2 15 17 +2 31 53 55 +2 61 +∞

L0 11 15 17 28 31 53 55 56 61 +∞

Startujemy z Listy L3 ,
1 Jak poprzednio znajdujemy miejsce 7,
2 Wstawiamy element na miejsce 7 do listy L0 ,
3 Rzucamy monet¡ poniewa» wypadª orzeª wstawiamy element 55 do listy
L1 ,
4 Rzucamy monet¡ poniewa» wypadª orzeª wstawiamy element 55 do listy
L2 ,
5 Rzucamy monet¡ poniewa» wypadª orzeª wstawiamy element 55 do listy
L3 ,
6 Rzucamy monet¡ poniewa» wypadªa reszka to ko«czymy wstawia¢ element
55 do kolejnych list,
7 Modykujemy informacje o kolejnych skokach w listach. 9 / 24
Podstawowe struktury danych: LISTA (SkipLista)
Implementacja listy za pomoc¡ skiplisty:

Wykonanie operacji remove(L, 3)


L3 +5 31 +2 55 +∞ +∞

L2 +3 17 +2 31 53 55 +∞ +∞

L1 +2 15 17 +2 31 53 55 +2 61 +∞

L0 11 15 17 28 31 53 55 56 61 +∞

Startujemy z Listy L3 ,
1 Jak poprzednio znajdujemy miejsce 3,
2 Usuwamy element 17 znajduj¡cy si¦ na pozycji 3 ze wszystkich list,
3 Modykujmey skoki na listach.

10 / 24
Podstawowe struktury danych: LISTA (SkipLista)
Implementacja listy za pomoc¡ skiplisty:
Zª. ±red. Zª. pesym.
Operacja Dziaªanie
poj. operacji poj. operacji
f ront(L) L[1] O(1) O(1),
push(L, x) L = [x]&L O(1) O(1),
pop(L) L = L[2..|L|] O(1) O(1),
rear(L) L[|L|] O(1) lub O(log n) O(1) lub O(n),
set(L, i, x) L[i] = x O(log n) O(n),
get(L, i) L[i] O(log n) O(n),
L = L[1, . . . , i − 1]
add(L, i, x) O(log n) O(n),
&[x]&L[i, . . . , |L|]
L = L[1, . . . , i − 1]
remove(L, i) O(log n) O(n),
&L[i + 1, . . . , |L|]
eject(L) L = L[1, .., |L| − 1] O(1) lub O(log n) O(1) lub O(n),
empty(L) L = [] O(n) O(n).

11 / 24
Podstawowe struktury danych: LISTA (SkipLista)
Funkcje pomocnicze
▶ searchP os(i) - oznacza funkcje zwracaj¡c¡ wska¹nik do elementu w L0 na
miejscu i,
▶ searchElmt(x) - oznacza funkcj¦ zwracaj¡c¡ wska¹nik do elementu x, w
li±cie L0 .
Jak ªatwo zauwa»y¢, aby wykona¢ takie operacje set, get, add, remove
trzeba najpierw albo odnale¹¢ odpowiedni element searachElmt(i), albo
miejsce gdzie ten element powinnien si¦ znale¹¢ searachP os(i).
Po znalezieniu elementu, albo pozycji wykonanie operacji
set, get, add, remove zajmuje O(H) kroków, gdzie H oznacza ostatni
numer niepustej listy, czyli
Li ̸= ∅ dla i ∈ {1, . . . , H}
Li = ∅ dla i ∈ {H + 1, . . . , +∞}

±rednia zªo»ono±¢ tych operacji zale»y zatem od h i zªo»ono±ci operacji


searchP os(i) albo searchElmt(i) gdzie dominuj¡cymi operacjami s¡
porównania.
12 / 24
Podstawowe struktury danych: LISTA

Metody szacowania ilo±ci porówna« wykonywanych przez funkcje


searchP os(i) czy searchElmt(x) sa praktycznie takie same. Zatem
oszacujemy ilo±¢ ±redni¡ porówna« dla searchP os(i).
Id¡c po ±cie»ce wyszukiwania wstecz
L3 +5 31 +∞ +∞

L2 +3 17 +2 31 53 +∞ +∞

L1 +2 15 17 +2 31 53 +2 61 +∞

L0 11 15 17 28 31 53 56 61 +∞

wida¢, »e zawsze idziemy w gór¦ gdy si¦ da, a gdy si¦ nie da to idziemy w
lewo.

13 / 24
Podstawowe struktury danych: LISTA (SkipLista)

Je±li przez
▶ h oznaczymy zmienn¡ losow¡ okreslaj¡c¡ wysoko±¢ H naszej struktury
▶ si zmienn¡ losow¡ okre±laj¡c¡ ilo±¢ kroków w lewo (id¡c wstecz), które
wykonamy na li±cie Li ,
L3 +5 31 +∞ +∞

L2 +3 17 +2 31 53 +∞ +∞

L1 +2 15 17 +2 31 53 +2 61 +∞

L0 11 15 17 28 31 53 56 61 +∞

to ±rednia ilo±¢ porówna« wykonanych przez searchP os(i) wynosi:


+∞
 
X
E h+ si
i=0

14 / 24
Podstawowe struktury danych: LISTA (SkipLista)

Twierdzenie
searchP os mo»na
‘rednia ilo±¢ porówna« przy wykonaniu oszacowa¢ przez

+∞
 
X
E h+ si ¬ 2 log2 (n) + 5
i=0

Dowód:

Liniowo±¢ warto±ci ±redniej E Xi = i=0 E(Xi ) daje:


Xn  Xn
i=0

+∞ +∞
 
X X
E h+ si = E(h) + E (si )
i=0 i=0

zatem oddzielnie mo»na szacowa¢ E(h) oraz E(si ).

15 / 24
Podstawowe struktury danych: LISTA (SkipLista)

Lemat
‘rednia wysoko±¢ struktury E(h) jest ograniczona od góry przez log2 n + 3

zgodnie z metod¡ wstawiania elementów do list dowolny element x ∈ L0


nale»y do Li z prawdopodobie«stwem 21i zatem oczekiwana ilo±¢
elementów w li±cie Li to:
n
E (|Li |) =
2i
je±li przez I1 oznaczymy zmienna losow¡
(
1, dla Li ̸= ∅
Ii =
0, dla Li = ∅
to
+∞  +∞
X X
E(h) = E Ii = E (Ii ) .
i=0 i=0

16 / 24
Podstawowe struktury danych: LISTA (SkipLista)

Poniewa» Ii ¬ |Li | to
E(Ii ) ¬ E (|Li |)

zatem:
+∞  +∞
X X
E(h) = E Ii = E (Ii )
i=0 i=0
⌊log2 n⌋ +∞
X X
= E (Ii ) + E (Ii )
i=0 i=⌊log2 n⌋+1
⌊log2 n⌋ +∞
X X n
¬ 1+ i
i=0 i=⌊log2 n⌋+1 2
+∞
X 1
¬ log2 n + 1 +
i=0 2i
= log2 n + 3

17 / 24
Podstawowe struktury danych: LISTA (SkipLista)

Lemat
Warto±¢ oczekiwana ilo±ci kroków w li±cie
(
1, dla i ¬ ⌊log2 n⌋,
E(si ) ¬
|Li |, dla dowolnego i,

Oczywi±cie ilo±¢ kroków po danej li±cie nie mo»e by¢ wi¦ksza od ilo±ci
elementów w tej li±cie, zatem si ¬ |Li |, zatem E(si ) ¬ E(|Li |) ¬ 2ni .
Dla i ¬ ⌊log2 n⌋ oznaczmy
(
1, gdy na li±cie Li wykonamy j-ty krok
Jj,i =
0, w przeciwnym przypadku
mamy E(Jj,i ) = 1
2j dla j ¬ |Li | oraz E(Ji,i ) = 0 dla j > |Li |
! !
+∞ |Li | +∞
X X X 1
E(si ) = E Jj,i =E Jj,i ¬ =1
j=1 j=1 j=1 2j

dla i ¬ ⌊log2 n⌋.


18 / 24
Podstawowe struktury danych: LISTA (SkipLista)

Zbieraj¡c te oszacowania z poprzednich lematów otrzymamy


+∞ +∞
 
X X
E h+ si = E(h) + E (si )
i=0 i=0
⌊log2 n⌋ +∞
X X
¬ E(h) + E (si ) + E (si )
i=0 i=⌊log2 n⌋+1
+∞
X n
¬ log2 n + 3 + log2 n + 1 + i
i=⌊log2 n⌋+1 2
+∞
X 1
¬ log2 n + 3 + log2 n + 1 +
i=1 2i
¬ 2 log2 n + 5

co ko«czy dowód twierdzenia.

19 / 24
Podstawowe struktury danych: LISTA

Twierdzenie
‘redni czas wykonania operacji searchP os(i) i searchElmt(x) wynosi co
najmniej Ω(log n), a tym samym ±redni czas operacji add(x, L) wynosi tak»e
co najmniej Ω(log n).

Uzasadnienie tego faktu jest proste je±li zauwa»ymy, »e maj¡c dowoln¡


permutacje elementów x1 , x2 , . . . , xn i wykonuj¡c kolejno n operacji
wstawienia tych elementów do listy add(xi , L) dla i = 1, . . . n, a nast¦pnie
wypisuj¡c elementy z listy L0 dostaniemy ci¡g posortowany.
Poniewa» ±redni czas sortowania elementów ustalonego algorytmu wynosi
co najmniej Ω(n log n), równie» dla takiego algorytmu jak powy»ej, to
koszt wypisywania elementów posortowanych zajmuje czas O(n). Zatem
czas ±redni wstawienia elementów add(xi , L) musi wynosi¢ co najmniej
Ω(n log n)
n = Ω(log n).
Uwaga: Nale»aªoby jeszcze pokaza¢, »e ±redni czas sortowania dla dowlonego
algorytmu sortowania przez porównanie wynosi Ω(n log n). Dowód mo»na
przeprowadzi¢ poprzez modykacj¦ wcze±niejszego dowodu na pesymistyczn¡
zªo»ono±¢ algorytmu sortowania albo przez zastosowanie metody kompresji.
20 / 24
Podstawowe struktury danych: LISTA
Implementacja listy za pomoc¡ drzewa binarnego:

W w¦¹le trzymamy informacj¦ ile jest w¦zªów w lewym poddrzewie.


Kolejne w¦zªy zgodne z porz¡dkiem inorder.
56 : 6

15 : 1 61 : 0

11 : 0 28 : 1

17 : 0 31 : 0

55 : 0

Operacja get(L, 5)
1 poniewa» lewe poddrzewo w¦zªa 56 ma 6 wierzchoªków, to miejsce 5 jest w
lewym poddrzewie,
2 poniewa» w¦zeª 15 ma 1 wierzchoªek w leweym poddrzewie to w prawym
b¦dziemy szuka¢ miejsca 3,
3 poniewa» w¦zeª 28 ma 1 wierzchoªek w leweym poddrzewie to w prawym
b¦dziemy szuka¢ miejsca 1,
4 znaleziony w¦zeª to 31.
21 / 24
Podstawowe struktury danych: LISTA
Implementacja listy za pomoc¡ drzewa binarnego:

‘redni koszt dªugo±ci ±cie»ek przy takim drzewie wynosi A(Xn ) = 2.


56 : 6

15 : 1 61 : 0

11 : 0 28 : 1

17 : 0 31 : 0

55 : 0

11 15 17 28 31 55 56 61

22 / 24
Podstawowe struktury danych: LISTA
Implementacja listy za pomoc¡ drzewa binarnego:

Zmiana struktury drzewa, przy zachowaniu kolejno±ci w¦zªów w porz¡dku


inorder obni»a ±redni¡ dªugo±¢ ±cie»ki z A(Xn ) = 2 do A(Xn ) = 1.75.
56 : 6

28 : 3 61 : 0

15 : 1 31 : 0

11 : 0 17 : 0 55 : 0

11 15 17 28 31 55 56 61

23 / 24
Podstawowe struktury danych: LISTA
Implementacja listy za pomoc¡ drzewa binarnego:

Kolejna zmiana struktury drzewa zachowuj¡c¡ porz¡dek inorder obni»a


jeszcze bardziej ±redni¡ dªugo±¢ ±cie»ki do A(Xn ) = 1.625.
31 : 4

15 : 1 56 : 1

11 : 0 17 : 0 55 : 0 61 : 0

28 : 0

11 15 17 28 31 55 56 61

Uwaga: Wykonuj¡c odpowiedni¡ dynamiczna modykacj¦ drzewa podczas


wykonywania operacji na takim drzewie (ró»ne typy drzew zostan¡ pokazane
pó¹niej) mo»na zapewni¢, »e ±rednia dªugo±¢ ±cie»ek zawsze b¦dzie wynosi¢
O(log n).
24 / 24
Podstawowe struktury danych: LISTA
Implementacja listy za pomoc¡ odpowiedniego typu drzewa binarnego:
Operacja Dziaªanie Zª. ±rednia Zª. pesym.
f ront(L) L[1] O(log n) O(log n),
push(L, x) L = [x]&L O(log n) O(log n),
pop(L) L = L[2..|L|] O(log n) O(log n),
rear(L) L[|L|] O(log n) O(log n),
set(L, i, x) L[i] = x O(log n) O(log n),
get(L, i) L[i] O(log n) O(log n),
L = L[1, . . . , i − 1]
add(L, i, x) O(log n) O(log n),
&[x]&L[i, . . . , |L|]
L = L[1, . . . , i − 1]
remove(L, i) O(log n) O(log n),
&L[i + 1, . . . , |L|]
eject(L) L = L[1, .., |L| − 1] O(log n) O(log n),
empty(L) L = [] O(n) O(n).

25 / 24

You might also like