Algorytmy Ksiazka

background image

SPIS TRE

ĝCI

WST

ĉP............. ........................................................................................3

1 A

LGORYTMY I MODELE OBLICZE

ē

................................................... 7

1.1

Poj

Ċcia podstawowe................................................................................ 7

1.2

Z

áoĪonoĞü algorytmu .............................................................................. 9

1.3

Model obliczeniowy RAM ................................................................... 14

1.3.1

Opis maszyny RAM...........................................................................................14

1.3.2

Uproszczony j

Ċzyk programowania..................................................................18

1.3.3

Z

áoĪonoĞü pesymistyczna i oczekiwana ............................................................21

1.3.4

Z

áoĪonoĞü programów w jĊzyku RAM ..............................................................23

1.3.5

Z

áoĪonoĞü programów w pseudokodzie............................................................26

2

S

TRUKTURY DYNAMICZNE I REKURSJA

.................................... 31

2.1

Wprowadzenie ...................................................................................... 31

2.2

Listy ...................................................................................................... 31

2.2.1

Definicje i reprezentacja pami

Ċciowa ..............................................................31

2.2.2

Podstawowe operacje na listach ......................................................................33

2.3

Stosy i kolejki ....................................................................................... 36

2.3.1

Stosy .................................................................................................................36

2.3.2

Kolejki ..............................................................................................................38

2.4

Obliczanie warto

Ğci wyraĪeĔ z wykorzystaniem stosu......................... 39

2.5

Grafy ..................................................................................................... 44

2.5.1

Grafy skierowane i nieskierowane ...................................................................44

2.5.2

Sposoby reprezentowania grafów ....................................................................46

2.6

Drzewa .................................................................................................. 48

2.6.1

Definicje ...........................................................................................................48

2.6.2

Drzewa binarne ................................................................................................50

2.6.3

U

Īycie struktur wskaĨnikowych........................................................................54

2.7

Rekursja ................................................................................................ 56

3

Z

ASTOSOWANIE DRZEW I ALGORYTMY PRZESZUKIWANIA

...... 61

3.1

Drzewa przeszukiwa

Ĕ binarnych .......................................................... 61

- 5 -

3.1.1

Przeszukiwanie w drzewach BST ..................................................................... 62

3.1.2

Inne operacje na drzewach BST....................................................................... 63

3.2

Kopce ....................................................................................................66

3.2.1

Definicja i w

áasnoĞü kopca .............................................................................. 66

3.2.2

Algorytmy na kopcach...................................................................................... 68

3.2.3

Kolejki priorytetowe......................................................................................... 72

3.3

Przeszukiwanie w drzewach .................................................................76

3.3.1

Typy zada

Ĕ przeszukiwania.............................................................................. 76

3.3.2

Strategie wszerz i w g

áąb.................................................................................. 79

3.3.3

Przeszukiwanie sterowane i niesterowane ....................................................... 81

3.3.4

Przeszukiwanie pe

áne ....................................................................................... 82

3.3.5

Generowanie dróg rozwi

ązaĔ .......................................................................... 83

4

S

ORTOWANIE

.............................................................................87

4.1

Wprowadzenie ......................................................................................87

4.2

Algorytmy oparte na porównaniach......................................................89

4.2.1

Drzewa decyzyjne............................................................................................. 89

4.2.2

Dolne ograniczenie na czas sortowania .......................................................... 91

4.2.3

Algorytmy asymptotycznie optymalne .............................................................. 92

4.3

Sortowanie w czasie liniowym..............................................................97

4.3.1

Sortowanie przez zliczanie ............................................................................... 98

4.3.2

Sortowanie kube

ákowe.................................................................................... 100

5

B

IBLIOGRAFIA

..........................................................................104

DODATEK

Z

ADANIA NA EGZAMINY I KOLOKWIA

...................................................105

- 6 -

background image

1 Algorytmy i modele oblicze

Ĕ

1.1 Poj

Ċcia podstawowe

Poj

Ċciem

algorytm okre

Ğla siĊ najczĊĞciej pewien przepis (sposób

post

Ċpowania), który ma prowadziü do rozwiązania okreĞlonego zadania.

Przyjmuje si

Ċ, Īe przepis ten jest na tyle precyzyjny, Īe posáugiwanie siĊ nim

polega wy

áącznie na automatycznym wykonywaniu zawartych tam poleceĔ.

Zak

áada siĊ dalej, Īe polecenia wystĊpujące w algorytmie są wykonywalne, tzn.

dost

Ċpne, a pisząc algorytm wystarczy siĊ nimi jedynie posáuĪyü. Zestaw

dost

Ċpnych poleceĔ zaleĪy od przyjĊtego modelu, w którym mają byü

realizowane obliczenia, okre

Ğlanego jako model obliczeĔ. Na rys.1.1 pokazano

znane z literatury przyk

áady modeli obliczeĔ [1].

MODELE OBLICZE

ē

Maszyna ze swobodnym

dost

Ċpem do pamiĊci

i pami

Ċtanym programem

(model RASP)

Maszyna ze swobodnym

dost

Ċpem do pamiĊci
(model RAM)

Maszyna Turinga

(elementarny model

oblicze

Ĕ)

Rys.1.1 Przyk

áady modeli obliczeĔ.

Wykonalno

Ğü moĪna rozpatrywaü takĪe w odniesieniu do pewnego zbioru

obiektów i dost

Ċpnych w nim pierwotnych operacji. Zbiór taki nazywa siĊ

dziedzin

ą algorytmiczną [4].

Obok wykonalno

Ğci, jako istotne dla algorytmów rozwaĪa siĊ takĪe pojĊcia

wej

Ğcia i wyjĞcia. WejĞcie oznacza zwykle pewne dane pobierane przez

algorytm w celu ich przetworzenia, podczas gdy wyj

Ğcie odnosi siĊ do wyniku

dzia

áania algorytmu. WaĪną wáaĞciwoĞcią wymaganą od algorytmu jest jego

sko

ĔczonoĞü, co oznacza, Īe algorytm powinien zakoĔczyü swoje dziaáanie po

wykonaniu sko

Ĕczonej liczby operacji. Dla algorytmów obowiązuje takĪe

- 7 -

okre

ĞlonoĞü, tzn. wymóg, aby kaĪda operacja w algorytmie byáa sformuáowana

w sposób zapewniaj

ący jej jednoznaczną interpretacjĊ. Zestawienie

wymienionych cech algorytmów pokazuje rys.1.2, a bardziej pe

áne ich

omówienie zawiera praca [7].

jest wykonalny

jest okre

Ğlony

posiada

wyj

Ğcie

posiada

wej

Ğcie

dochodzi do

punktu ko

Ĕcowego

Algorytm

Rys.1.2 Cechy algorytmów.

Do podstawowych pyta

Ĕ pojawiających siĊ w trakcie teoretycznych badaĔ nad

obliczeniami nale

Īą m.in.:

x Jak dla okreĞlonego zadania znaleĨü efektywny algorytm?
x JeĞli algorytm juĪ znaleziono, to jak porównaü go z innymi, które rozwiązują

podobne zadania?

x Jak udowodniü poprawnoĞü algorytmu?
x W jakim sensie moĪna wykazaü, Īe pewne algorytmy są „najlepszymi z

mo

Īliwych”?

Spo

Ğród dziedzin zajmujących siĊ algorytmami istotne znaczenie ma analiza

algorytmów, której zasadnicze kierunki dotycz

ą poprawnoĞci i záoĪonoĞci

obliczeniowej (rys.1.3).

ANALIZA ALGORYTMÓW

Poprawno

Ğü

algorytmów

Z

áoĪonoĞü

obliczeniowa

Rys.1.3 Kierunki bada

Ĕ analizy algorytmów.

- 8 -

background image

Poprawno

Ğü dotyczy przede wszystkim pojĊü i metod związanych z

dowodzeniem poprawno

Ğci algorytmów, takich jak: wáasnoĞü stopu, czĊĞciowa

poprawno

Ğü, metoda niezmienników itp. Zagadnienia te są na tyle waĪne, aby

po

ĞwiĊciü im odrĊbny wykáad i nie bĊdą tutaj omawiane.

Dziedzin

ą, której poĞwiĊcimy znacznie wiĊcej miejsca bĊdzie natomiast

z

áoĪonoĞü obliczeniowa algorytmów i związane z nią pojĊcia, do których naleĪą

m.in.: z

áoĪonoĞü czasowa, pamiĊciowa, Ğrednia i pesymistyczna. Ten obszar

analizy algorytmów koncentruje si

Ċ na okreĞlaniu zasobów (czas obliczeĔ i

pami

Ċü), jakie są potrzebne do wykonania badanego algorytmu.

1.2 Z

áoĪonoĞü algorytmu

Oceny z

áoĪonoĞci algorytmu moĪna dokonaü wedáug róĪnych kryteriów. CzĊsto

stosowana jest metoda polegaj

ąca na badaniu, jak zwiĊksza siĊ czas obliczeĔ

lub wielko

Ğü pamiĊci potrzebnej do wykonania algorytmu, w miarĊ wzrostu

rozmiaru danych wej

Ğciowych. Rozmiar tych danych nazywaü bĊdziemy

rozmiarem zadania, albo rozmiarem wej

Ğcia, przyjmując, Īe jest to konkretna

liczba charakteryzuj

ąca objĊtoĞü danych wejĞciowych. Jako przykáady

rozmiarów wej

Ğcia moĪna wymieniü:

x liczbĊ elementów tablicy wejĞciowej w algorytmach sortowania,
x liczbĊ krawĊdzi grafu w algorytmach operujących na grafach,
x wymiary macierzy w zadaniu mnoĪenia macierzy.

Czas potrzebny na wykonanie algorytmu jako funkcja rozmiaru zadania jest
nazywany z

áoĪonoĞcią czasową tego algorytmu. Charakter tej záoĪonoĞci przy

d

ąĪeniu do wartoĞci granicznej wraz ze wzrostem rozmiaru zadania jest

okre

Ğlany jako asymptotyczna záoĪonoĞü czasowa. W analogiczny sposób

mo

Īna zdefiniowaü pojĊcia záoĪonoĞci pamiĊciowej i asymptotycznej záoĪonoĞci

pami

Ċciowej.

Wprowadzenie asymptotycznej z

áoĪonoĞci algorytmu jest szczególnie waĪne,

gdy

Ī przy jej pomocy moĪna okreĞliü rozmiar zadaĔ, które mogą byü

rozwi

ązane za pomocą tego algorytmu. JeĞli np. algorytm przetwarza wejĞcie o

rozmiarze

, w czasie

cn

, gdzie

jest pewn

ą staáą, wówczas mówimy, Īe

z

áoĪonoĞü czasowa tego algorytmu jest rzĊdu

, co zapisujemy jako

i

n

2

c

n

2

O n

2

- 9 -

czytamy "du

Īe o od n kwadrat". Ogólnie biorąc, pewna nieujemna funkcja

jest

f n

n

O g

, je

Ğli istnieje taka staáa

,

Īe

c

d

d

f n

n

O g n

f n

O g

c

cg n

a)

O g n

n

0

f n

c

cg n

0

cg n

dla wszystkich

oprócz pewnego, by

ü moĪe pustego, zbioru nieujemnych

warto

Ğci

n

.

Symbol

jest zaliczany do tzw. notacji asymptotycznych, u

Īywanych

do opisu asymptotycznego czasu dzia

áania algorytmów. Na rysunku 1.4a

podano interpretacj

Ċ graficzną notacji

. Wynika z niej,

Īe przy pomocy

zapisu

podaje si

Ċ górne ograniczenie funkcji z dokáadnoĞcią

do sta

áego wspóáczynnika. Bardziej precyzyjnie zapis ten oznacza, Īe istnieją

dodatnie sta

áe

i

takie,

Īe na prawo od

n

warto

Ğü

O

n

n

0

0

f n

jest zawsze nie

wi

Ċksza od

.

Ponadto na rys.1.4b i 1.4c przedstawiono w podobny sposób notacje

4

i

,

b

Ċdące takĪe przykáadami notacji asymptotycznych.

:

f n

cg n

f n

n

f n

n

0

c)

f n

g n

4

c g n

1

c g n

2

n

n

f n

cg n

n

0

f n

g n

:

b)

Rys.1.4 Graficzna interpretacja notacji asymptotycznych.

W odró

Īnieniu od notacji

, która ogranicza funkcj

Ċ z góry, notacja

(rys.1.4b) ogranicza funkcj

Ċ z doáu. Zapis

O

:

g n

:

0

oznacza,

Īe istnieją

dodatnie sta

áe

i

takie,

Īe na prawo od

n

warto

Ğü

n

0

f n

jest zawsze

wi

Ċksza od

. Przedstawiona na rys.1.4c notacja pozwala szacowa

ü

funkcj

Ċ z doáu i z góry. Pisząc zatem

g n

4

f n

wskazujemy,

Īe istnieją

- 10 -

background image

dodatnie sta

áe

,

i

n

takie,

Īe na prawo od

n

warto

Ğü

c

1

c

2

0

0

f n

jest zawsze

wi

Ċksza od

i nie wi

Ċksza od

c g n

1

c g n

2

.

f n

n

2

n

 3

1

2

n

2

f n

g

c

n

0

n

2

2

d

 n

3

1

2

n

0

n

3

1

2

3

2



d

n

c

1

2

c

0

Przyk

áad 1.1

Przyjmuj

ąc

oraz

g n

wyka

Īemy, Īe

n

4

.

Aby tego dokona

ü, naleĪy wyznaczyü dodatnie staáe

,

c

i

takie,

Īe

1

2

c n

c n

1

2

2

d

dla

n

.

(1.1)

t

Dziel

ąc nierównoĞü (1.1) przez

otrzymujemy zale

ĪnoĞü

n

2

c

c

1

2

1

2

d



d

z której wynika,

Īe nierównoĞü

jest spe

ániona dla kaĪdego

,

je

Ğli przyjąü

n

t 1

c

2

, a nierówno

Ğü

c

n

1

1

2

3

d



jest spe

ániona dla kaĪdego

, je

Ğli przyjąü

n

t 7

c

1

1

14

. St

ąd dla

c

,

1

1

14

2

1

2

i

n

zachodzi

nierówno

Ğü (1.1), co oznacza, Īe

7

f n

g n

4

.

Mog

áoby siĊ wydawaü, Īe imponujący wzrost szybkoĞci wspóáczesnych

komputerów powoduje,

Īe prace nad poszukiwaniem efektywnych algorytmów

nie s

ą uzasadnione. Celem kolejnych dwóch przykáadów bĊdzie wykazanie, Īe

tak nie jest, gdy

Ī efektywne algorytmy mogą w sposób nie mniej istotny jak

rozwój sprz

Ċtu wpáywaü na wydajnoĞü komputerów (mierzoną np. rozmiarem

zada

Ĕ, które mogą byü rozwiązywane).

- 11 -

Przyk

áad 1.2 [1]

W dwóch pierwszych kolumnach tab.1.1 zamieszczono pi

Ċü przykáadowych

algorytmów wraz z ich z

áoĪonoĞcią czasową, rozumianą tutaj jako liczba

jednostek czasu potrzebnych do obróbki (przetworzenia) wej

Ğcia o rozmiarze n.

Je

Ğli za jednostkĊ czasu przyjąü jedną milisekundĊ, to algorytm

mo

Īe w

ci

ągu sekundy przetworzyü wejĞcie o rozmiarze 1000, natomiast algorytm

wej

Ğcie o rozmiarze zaledwie 9.

A

1

A

5

Tab.1.1

Z

áoĪonoĞci czasowe i maksymalne rozmiary zadaĔ dla wybranych

algorytmów.

Algorytm

Z

áoĪonoĞü

Maksymalny rozmiar zadania

czasowa

1 sekunda

1 minuta

1 godzina

A

1

n

1000

6

˜10

4

3,6

˜10

6

A

2

n

n

lg

140

4893

2,0

˜10

5

A

3

n

2

31

244

1897

A

4

n

3

10

39

153

A

5

2

n

9

15

21

W kolejnych kolumnach tab.1.1 zamieszczono maksymalne rozmiary zada

Ĕ

które mog

ą byü przetworzone przez rozwaĪane algorytmy, jeĞli za caákowity

czas oblicze

Ĕ przyjąü odpowiednio 1 sekundĊ, 1 minutĊ i 1 godzinĊ.

Za

áóĪmy dalej, Īe w pewnym okresie szybkoĞü komputerów wzrasta 10-krotnie.

W tab.1.2 pokazano, jak wzrosn

ą rozmiary zadaĔ, które mogą byü przetworzone

przez algorytmy

y

, w wyniku takiego wzrostu szybko

Ğci komputerów.

A

1

A

5

Tab.1.2 Wp

áyw zwiĊkszenia szybkoĞci komputera na maksymalny rozmiar zadania.

Algorytm

Z

áoĪonoĞü

Maksymalny rozmiar zadania

czasowa

przed zwi

Ċkszeniem

po zwi

Ċkszeniu

A

1

n

s

1

10

1

s

A

2

n

n

lg

s

2

~

10

dla du

Īych

2

s

s

2

A

3

n

2

s

3

3,16

s

3

A

4

n

3

s

4

2 15

4

, s

A

5

2

n

s

5

s

5

3 3

 ,

- 12 -

background image

Zauwa

Īmy, Īe dla algorytmu

10-krotne zwi

Ċkszenie prĊdkoĞci komputera

pozwala zwi

Ċkszyü rozmiar zadania, które moĪe byü rozwiązane zaledwie o 3,

podczas gdy w przypadku algorytmu

rozmiar ten si

Ċ potraja.

A

5

A

3

Porównajmy teraz efekty zwi

Ċkszenia szybkoĞci komputerów z efektami

zastosowania bardziej efektywnego algorytmu. W tym celu powró

ümy do

tab.1.1 i przyjmijmy za podstaw

Ċ porównania jedną minutĊ. Widaü przy tym, Īe

zamiana algorytmu

na algorytm

pozwala rozwi

ązaü zadanie 6-krotnie

wi

Ċksze. Natomiast zamiana

na

pozwala rozwi

ązaü zadanie o rozmiarze

125-krotnie wi

Ċkszym. Wyniki te oznaczają, Īe polepszenie osiągów

spowodowane zastosowaniem bardziej efektywnego algorytmu mo

Īe wyraĨnie

przewy

Īszyü zyski wynikające ze zwiĊkszenia szybkoĞci komputerów.

A

4

A

3

A

2

A

4

Przyk

áad 1.3 [5]

Zak

áada siĊ, Īe równolegle na dwóch komputerach o róĪnej mocy obliczeniowej

jest sortowana tablica zawieraj

ąca milion elementów (

n

1000000

).

Przyjmujemy dalej,

Īe na superkomputerze wykonującym 100 milionów

operacji na sekund

Ċ zastosowano algorytm sortowania o záoĪonoĞci

, a na

mikrokomputerze wykonuj

ącym 1 milion operacji na sekundĊ zastosowano

inny algorytm sortowania o z

áoĪonoĞci

. Przedstawimy teraz

szacunkowe obliczenia czasów jakie potrzebuj

ą oba komputery na posortowanie

tablicy wej

Ğciowej.

2

2

n

50n lg n

Dla superkomputera:

2 10

10

20000

5 56

6

2

8

˜

|

|

instrukcji

instrukcji sek

sek

godz

/

.

.

,

.

Dla mikrokomputera:

50 10

10

10

1000

16 67

6

6

6

˜

|

|

lg

/

.

.

,

mi

instrukcji

instrukcji sek

sek

n.

U

Īywając zatem algorytmu, którego czas dziaáania jest opisany funkcją

ni

Īszego rzĊdu (nawet jeĞli zostaá on napisany przez sáabszego programistĊ)

mikrokomputer dzia

áa okoáo 20-krotnie szybciej niĪ superkomputer.

- 13 -

W dotychczasowych rozwa

Īaniach zwracaliĞmy uwagĊ przede wszystkim na to,

jakiego rz

Ċdu jest wzrost záoĪonoĞci. NaleĪy jednak pamiĊtaü o tym, Īe w

niektórych przypadkach istotna mo

Īe okazaü siĊ takĪe wartoĞü wspóáczynnika

sta

áego. W szczególnoĞci, przy mniejszym rozmiarze zadaĔ, algorytmy o duĪym

stopniu wzrastania z

áoĪonoĞci lecz mniejszym wspóáczynniku staáym mogą

okaza

ü siĊ bardziej efektywne od algorytmów o mniejszym stopniu wzrastania

z

áoĪonoĞci, ale duĪym wspóáczynniku staáym. Dla ilustracji przyjmijmy liczbĊ

sortowanych elementów w ostatnim przyk

áadzie jako n=10. W przypadku tak

ma

áego rozmiaru zadania algorytm uĪyty przez superkomputer wymaga jedynie

200 instrukcji, podczas gdy algorytm u

Īyty przez mikrokomputer ok. 1500.

Oznacza to,

Īe ze wzglĊdu na wiĊkszy wspóáczynnik staáy w wyraĪeniu na

z

áoĪonoĞü algorytmu korzyĞci z zastosowania dla mikrokomputera bardziej

wydajnego algorytmu uwidoczni

ą siĊ dopiero dla zadaĔ o wiĊkszym rozmiarze.

1.3 Model obliczeniowy RAM

1.3.1

Opis maszyny RAM

Dalsze rozwa

Īania na temat algorytmów i ich záoĪonoĞci poprzedzimy

wprowadzeniem hipotetycznego modelu maszyny (urz

ądzenia liczącego), za

pomoc

ą którego bĊdą realizowane nasze algorytmy. JednoczeĞnie przyjmiemy

pewne ustalenia odno

Ğnie tego, co bĊdzie okreĞlane pojĊciem „elementarny

krok oblicze

Ĕ”. Z literatury znane są róĪne modele obliczeĔ (por.rys.1.1),

nale

Īy jednak stwierdziü, Īe nie istnieje model uniwersalny, który byáby

najlepszy dla wszystkich przypadków.

Tutaj przedstawiony zostanie rozwa

Īany w [1] model maszyny ze swobodnym

dost

Ċpem do pamiĊci (model RAM – Random Access Machine). Model ten

reprezentuje maszyn

Ċ z jednym sumatorem, w której program nie jest

przechowywany w pami

Ċci, a zatem nie moĪe on modyfikowaü sam siebie.

Schemat modelu RAM (maszyny RAM) pokazano na rys.1.5. Maszyna sk

áada

si

Ċ z nastĊpujących trzech elementów:

x taĞmy wejĞciowej, z której dane mogą byü tylko czytane,
x taĞmy wyjĞciowej, na którą dane mogą byü tylko zapisywane,
x pamiĊci.

- 14 -

background image

Ta

Ğma wejĞciowa stanowi ciąg klatek, z których kaĪda moĪe zawieraü liczbĊ

ca

ákowitą. KaĪdorazowo, kiedy z taĞmy wejĞciowej zostanie odczytana liczba,

g

áowica czytająca jest przesuwana o jedną pozycjĊ w prawo. Analogicznie

ta

Ğma wyjĞciowa jest takĪe ciągiem klatek (na początku pustych), do których

maszyna mo

Īe tylko zapisywaü. Po zapisie do kolejnej klatki gáowica

zapisuj

ąca jest przesuwana o jedną klatkĊ w prawo. PamiĊü skáada siĊ z

rejestrów

, z których ka

Īdy moĪe przechowywaü (pamiĊtaü)

dowoln

ą liczbĊ caákowitą. Rejestr peáni w obliczeniach specjalną rolĊ i jest

nazywany

sumatorem. Na liczb

Ċ rejestrów nie nakáadamy górnego

ograniczenia, zak

áadając, Īe rozmiar zadania jest zawsze na tyle maáy, Īe mieĞci

si

Ċ ono w pamiĊci, a liczby caákowite biorące udziaá w obliczeniach mieszczą

si

Ċ w pojedynczych komórkach (rejestrach).

,...

,

,

,

3

2

1

0

r

r

r

r

0

r

PROGRAM

. . .

0

r

1

r

2

r

3

r

Sumator

Pami

Ċü

. . .

Ta

Ğma wejĞciowa

. . .

Ta

Ğma wyjĞciowa

Licznik

rozkazów

2

y

1

y

n

x

3

x

2

x

1

x

Rys.1.5 Schemat maszyny RAM [1].

Program maszyny RAM to ci

ąg poleceĔ (inaczej: instrukcji, rozkazów lub

komend), które mog

ą byü poprzedzone etykietą. Licznik rozkazów zawiera

numer kolejnego rozkazu do wykonania. Dok

áadny typ komend nie jest istotny,

o ile przypominaj

ą one te, które wystĊpują w realnych komputerach.

Przyjmiemy,

Īe są dostĊpne komendy arytmetyczne, wejĞcia/wyjĞcia oraz

komendy skoku bezwarunkowego i warunkowego, a tak

Īe wystĊpuje

mo

ĪliwoĞü adresowania poĞredniego. Wszystkie obliczenia są prowadzone na

sumatorze, którym jest rejestr

r

. Przyk

áadowy zestaw poleceĔ maszyny RAM

zamieszczono w tab.1.3.

0

- 15 -

Tab.1.3 Polecenia maszyny RAM.

L.p.

Kod

operacji

Adres

L.p.

Kod

operacji

Adres

1.

LOAD

operand

7.

READ

operand

2.

STORE

operand

8.

WRITE

operand

3.

ADD

operand

9.

JUMP

etykieta

4.

SUB

operand

10.

JGTZ

etykieta

5.

MULT

operand

11.

JZERO

etykieta

6.

DIV

operand

12.

HALT

W ogólnym przypadku komenda sk

áada siĊ z kodu operacji i adresu, który moĪe

by

ü operandem lub etykietą (wyjątkiem jest komenda HALT, gdzie adres nie

wyst

Ċpuje). Etykietą jest nazwa symboliczna, a operand moĪe naleĪeü do

jednego z trzech nast

Ċpujących typów:

=i

-

liczba ca

ákowita i; operand tego typu nazywamy literaáem,

i

-

zawarto

Ğü rejestru o numerze i (i powinno byü nieujemne),

*i

-

warto

Ğcią operandu jest zawartoĞü rejestru j, gdzie j jest liczbą

nieujemn

ą przechowywaną w rejestrze i (adresacja poĞrednia).

Rozwa

Īymy dalej pewne odwzorowanie c zbioru liczb caákowitych

nieujemnych na zbiór liczb ca

ákowitych takie, Īe

oznacza zawarto

Ğü

rejestru o numerze i. Odwzorowanie pozwala zatem przedstawi

ü mapĊ

pami

Ċci (rejestrów) maszyny RAM i wraz z zawartoĞcią licznika rozkazów

definiuje tzw. znaczenie programu w danej chwili. Na pocz

ątku przyjmuje siĊ

, oraz zak

áada, Īe licznik rozkazów wskazuje na pierwszą

komend

Ċ do wykonania, a taĞma wyjĞciowa jest pusta. Po wykonaniu pewnego

rozkazu

licznik rozkazów automatycznie wskazuje na rozkaz

za

wyj

ątkiem przypadków, kiedy rozkazem

k

-tym by

á któryĞ z nastĊpujących

rozkazów: JUMP, JGTZ, JZERO lub HALT.

)

(i

c

c

0

,

0

)

(

t

i

i

c

k

1



k

Aby w pewien formalny sposób opisa

ü dziaáanie komend z tab.1.3

wprowadzimy jeszcze funkcj

Ċ

a

v

wyznaczaj

ącą wartoĞü operandu w

nast

Ċpujący sposób:

a

i

i

v

i

c

i

v

i

c

c

i

v

*

.

- 16 -

background image

Opis komend maszyny RAM, z wykorzystaniem wprowadzonych notacji
zestawiono w tab.1.4.

Tab.1.4 Opis polece

Ĕ maszyny RAM.

Komenda

Opis dzia

áania

LOAD

a

a

v

c

m

0

, co oznacza zapis warto

Ğci operandu do

rejestru 0 (sumatora).

a

STORE

i

0

c

i

c

m

STORE

*

i

0

c

i

c

c

m

ADD

a

a

v

c

c



m 0

0

SUB

a

a

v

c

c



m 0

0

MULT

a

a

v

c

c

u

m 0

0

DIV

a

¬

¼

a

v

c

c

/

0

0

m

READ

i

m

i

c

kolejny symbol wej

Ğciowy

READ

*

i

m

i

c

c

kolejny symbol wej

Ğciowy

WRITE

a

a

v

jest zapisywane do tej klatki ta

Ğmy wyjĞciowej, przy której

aktualnie znajduje si

Ċ gáowica

JUMP

b

Licznik rozkazów jest ustawiany na komend

Ċ z etykietą

b

JGTZ

b

Je

Ğli

, to licznik rozkazów jest ustawiany na komend

Ċ z

etykiet

ą

b

; w przeciwnym razie na komend

Ċ nastĊpną

0

0

!

c

JZERO

b

Je

Ğli

0

0

c

, to licznik rozkazów jest ustawiany na komend

Ċ z

etykiet

ą

b

; w przeciwnym razie na komend

Ċ nastĊpną

HALT

Zatrzymanie programu

Przyk

áad 1.4

Wyznaczy

ü wartoĞü funkcji:

¯

®

­

t

1

dla

0

dla

0

n

n

n

n

f

n

.

Odpowiedni program dla maszyny RAM ma posta

ü:

Etykieta

Komenda

Adres

Komentarz

READ

1

Wczytaj liczb

Ċ n do rejestru 1

- 17 -

LOAD

1

Umie

Ğü n w sumatorze

JGTZ

dod

Wykonuj obliczenia tylko wtedy, gdy

n>0

WRITE

=0

W przypadku gdy n=0 wypisz 0

JUMP

Koniecjesli

Skocz na koniec programu

dod: LOAD

1

Umie

Ğü n w sumatorze

STORE

2

Zapisz n do rejestru 2

LOAD

1

Umie

Ğü n w sumatorze

SUB

=1

Oblicz n-1

STORE

3

Zapisz n-1 do rejestru 3

dopoki: LOAD

3

Umie

Ğü zawartoĞü rejestru 3( licznik

p

Ċtli) w sumatorze

JGTZ

Kontyn

Kontynuuj, je

Ğli w rejestrze 3 jest

liczba wi

Ċksza od 0

JUMP

Koniecdopoki

Skocz do wypisania wyniku

Kontyn: LOAD

2

Zapisz iloczyn cz

ąstkowy do sumatora

MULT

1

Pomnó

Ī iloczyn cząstkowy przez n

STORE

2

Zapisz nowy iloczyn cz

ąstkowy do

rejestru 2

LOAD

3

Umie

Ğü licznik pĊtli w sumatorze

SUB

=1

Odejmij 1 od licznika p

Ċtli

STORE

3

Zapisz now

ą wartoĞü licznika pĊtli w

sumatorze

JUMP

Dopoki

Skocz do sprawdzenia warunku p

Ċtli

Koniecdopoki: WRITE

2

Wypisz zawarto

Ğü rejestru 2 (tj.

obliczone

n

)

n

Koniecjesli: HALT

Koniec programu

1.3.2 Uproszczony j

Ċzyk programowania

Celem uzyskania bardziej przejrzystego zapisu algorytmów wykonywalnych w
ramach modelu RAM do

Ğü czĊsto uĪywa siĊ uproszczonego jĊzyka wyĪszego

poziomu, okre

Ğlanego jako pseudojĊzyk lub pseudokod [1, 5]. W

prezentowanych dalej przyk

áadach najczĊĞciej uĪywany bĊdzie jĊzyk

wzorowany na pseudokod zaproponowany w [5]. Poni

Īej przedstawiony

zostanie pewien nieformalny opis tego j

Ċzyka.

- 18 -

background image

1. Pseudokod tym ró

Īni siĊ od typowego jĊzyka programowania, Īe dopuszcza

dowolny typ opisu matematycznego, a nawet s

áownego, jeĞli tylko jest on w

pe

áni zrozumiaáy i moĪe zostaü przetáumaczony na komendy prostego

modelu, np. modelu RAM.

2. Nie ustala si

Ċ z góry dopuszczalnych typów danych, a zmiennymi są

zwykle liczby i tablice. Dodatkowe typy, jak: listy, kolejki, stosy, grafy itp.
s

ą wprowadzane w razie potrzeby. Tam, gdzie to moĪliwe, unika siĊ ich

formalnego opisu.

3. Stosuje si

Ċ tradycyjny zapis matematyczny oraz konstrukcje znane z

j

Ċzyków programowania typu Pascal i C. Do podstawowych operatorów

pseudokodu nale

Īą:

a) nadawanie

warto

Ğci

zmienna

m wyraĪenie

b) operator

warunkowy

je

Ğli warunek

to

operator(y)

inaczej

operator(y)

c) operator

p

Ċtli dopóki

dopóki

warunek

wykonuj

operator(y)

d) operator

p

Ċtli powtarzaj

powtarzaj

operator(y)

a

Ī_do warunek

e) operator

p

Ċtli dla

dla

zmienna

m wartoĞü_początkowa [w_dóá_]do wartoĞü_koĔcowa

wykonuj

operator(y)

4. Blok polece

Ĕ pseudojĊzyka (instrukcjĊ záoĪoną) wydzielamy za pomocą

nawisów klamrowych { i }. Mo

Īna takĪe stosowaü „wciĊcia” celem

zwi

Ċkszenia czytelnoĞci programu.

- 19 -

5. Symbol „

” oznacza,

Īe reszta wiersza jest komentarzem.

6. Wielokrotne przypisywanie w postaci

i

e

j

m

m

oznacza przypisanie

zmiennym

oraz warto

Ğci wyraĪenia

. Jest ono równowa

Īne

przypisaniu

áącznie z przypisaniem

i

j

j

e

j

i

e

m

m

.

7. Zmienne s

ą z zaáoĪenia lokalne w danej procedurze, chyba, Īe wyraĨnie

zaznaczono inaczej.

8. Dost

Ċp do elementu tablicy odbywa siĊ przez podanie jej nazwy oraz

indeksu

Īądanego elementu w nawiasie kwadratowym, np.

> @

i

A

jest

i

-tym

elementem tablicy

A

. Zapis

> @

j

A ..

1

oznacza natomiast podtablic

Ċ tablicy

A

z

áoĪoną z elementów

> @ > @

> @

j

A ,

1

A

A

,...

2

.

9. Dane z

áoĪone z kilku czĊĞci są zorganizowane jako obiekty záoĪone z

atrybutów (pól). Odwo

áanie do konkretnego atrybutu pewnego obiektu

nast

Ċpuje przez podanie nazwy tego obiektu w nawiasach kwadratowych

poprzedzonej nazw

ą atrybutu, np.

> @

x

f

jest odwo

áaniem do atrybutu

obiektu

f

x

.

10. Zmienna odpowiadaj

ąca tablicy lub obiektowi jest traktowana jako

wska

Ĩnik do danych reprezentujących tĊ tablicĊ lub ten obiekt. Dla

wszystkich pól

obiektu

f

x

przypisanie

x

y

m

powoduje

> @

>

x

f

y

f

@

.

Ponadto je

Ğli teraz wykonamy

> @

3

m

x

f

, to w nast

Ċpstwie nie tylko

, lecz tak

Īe

> @

3

x

f

> @

3

y

f

. Wska

Ĩnik, który na nic nie wskazuje

posiada specjaln

ą wartoĞü nil.

11. Parametry s

ą przekazywane do procedury przez wartoĞü, tzn., Īe

wywo

áywana procedura otrzymuje swoją kopiĊ parametrów, a zmiany

wewn

Ċtrzne tych kopii nie są widoczne przez program wywoáujący.

Obiekty s

ą przekazywane przez wskaĨniki do nich. JeĞli na przykáad obiekt

x

jest parametrem procedury, to przypisanie

y

x

m

wewn

ątrz procedury

nie jest widoczne na zewn

ątrz, ale przypisanie

> @

3

m

x

f

jest widoczne.

Przyk

áad 1.5

- 20 -

background image

Zapisany w pseudokodzie algorytm K.1.1 oblicza warto

Ğü funkcji z przykáadu

1.4.

K.1.1

POT

ĉGA-N-DO-N

1 czytaj r1
2 je

Ğli r1

d0 to pisz 0

3 inaczej { r2

m

r1

4

r3

m

r1-1

5

dopóki

r3>0

6

wykonuj

{ r2

m

r2*r1

7 r3

m

r3-1 }

8 pisz r2 }

Numerowanie wierszy programu w pseudokodzie pozwala

áatwiej odwoáywaü

si

Ċ do tych wierszy w opisach prezentowanych algorytmów.

Programy w pseudokodzie s

ą równowaĪne programom RAM w tym sensie, Īe

jest mo

Īliwe ich táumaczenie na program w jĊzyku maszyny RAM. Problem

takiej translacji stanowi jednak odr

Ċbne zagadnienie i nie bĊdzie tutaj

omawiany.

W literaturze z dziedziny algorytmów obok pseudokodów zbli

Īonych do

zdefiniowanego, s

ą uĪywane takĪe popularne jĊzyki programowania, np. Pascal

[3, 4] lub C [6].

1.3.3 Z

áoĪonoĞü pesymistyczna i oczekiwana

Jak ju

Ī wspomniano, dwa podstawowe wskaĨniki efektywnoĞci algorytmów

stanowi

ą záoĪonoĞü pamiĊciowa i záoĪonoĞü czasowa bĊdące funkcjami

rozmiaru wej

Ğcia. Za jednostkĊ záoĪonoĞci pamiĊciowej przyjmuje siĊ zwykle

s

áowo pamiĊci maszyny. Natomiast w przypadku záoĪonoĞci czasowej, która

powinna by

ü niezaleĪna od komputera, jĊzyka programowania i sposobu

zakodowania programu, rozwa

Īa siĊ tzw. operacje dominujące. Są to operacje

charakterystyczne dla danego algorytmu, a ich liczba jest proporcjonalna do
liczby wykona

Ĕ wszystkich operacji jednostkowych w dowolnej realizacji

komputerowej danego algorytmu [3]. Na przyk

áad w algorytmach wyznaczania

warto

Ğci wielomianów mogą to byü podstawowe operacje arytmetyczne, a w

algorytmach sortowania – operacje porównania dwóch elementów sortowanej

- 21 -

tablicy. Za jednostk

Ċ záoĪonoĞci czasowej przyjmuje siĊ wtedy wykonanie

jednej operacji dominuj

ącej.

Je

Ğli dla ustalonego rozmiaru wejĞcia w charakterze miary záoĪonoĞci przyjąü

najwi

Ċkszą ze záoĪonoĞci dla wszystkich moĪliwych wejĞü danego rozmiaru, to

taka z

áoĪonoĞü jest okreĞlana jako pesymistyczna. JeĞli natomiast jako miarĊ

z

áoĪonoĞci przyjąü pewną „Ğrednią” záoĪonoĞü dla wszystkich wejĞü danego

rozmiaru to tak

ą záoĪonoĞü okreĞlamy jako oczekiwaną. Zazwyczaj záoĪonoĞü

oczekiwana jest trudniejsza do okre

Ğlenia niĪ záoĪonoĞü pesymistyczna.

Poj

Ċcia záoĪonoĞci pesymistycznej i záoĪonoĞci oczekiwanej moĪna takĪe

wprowadzi

ü w sposób formalny. Uczynimy to w stosunku do záoĪonoĞci

czasowej u

Īywając nastĊpujących oznaczeĔ:

d

n

- rozmiar zestawu danych

d

,

n

D

- zbiór zestawów danych wej

Ğciowych rozmiaru

n

,

d

r

- Liczba operacji dominuj

ących dla zestawu danych wejĞciowych

,

d

n

X

- Zmienna losowa, której wartoĞcią jest

d

r

dla

n

D

d



,

nk

p

- Rozkáad prawdopodobieĔstwa zmiennej losowej

, tzn.

prawdopodobie

Ĕstwo, Īe dla danych rozmiaru

algorytm wykona

operacji dominuj

ących

n

X

n

k

0

t

k

.

Rozk

áad prawdopodobieĔstwa zmiennej losowej

wyznacza si

Ċ na

podstawie informacji o zastosowaniach rozwa

Īanego algorytmu. W pewnych

przypadkach mo

Īna zaáoĪyü, Īe jest to rozkáad równomierny, tzn. kaĪdy zestaw

danych rozmiaru

n

mo

Īe pojawiü siĊ na wejĞciu algorytmu z jednakowym

prawdopodobie

Ĕstwem.

n

X

Definicja 1.1

Pesymistyczna z

áoĪonoĞü czasowa algorytmu to funkcja rozmiaru wejĞcia

okre

Ğlona nastĊpująco:

^

`

n

D

d

d

r

n

W



:

sup

,

gdzie sup oznacza górny kres zbioru.

- 22 -

background image

Definicja 1.2

Oczekiwana z

áoĪonoĞü czasowa to funkcja rozmiaru wejĞcia okreĞlona

nast

Ċpująco

.

¦

t

0

k

nk

kp

n

A

Jest to zatem warto

Ğü oczekiwana zmiennej losowej

.

n

X

1.3.4 Z

áoĪonoĞü programów w jĊzyku RAM

W celu otrzymania z

áoĪonoĞci czasowej i pamiĊciowej programów RAM naleĪy

okre

Ğliü czas niezbĊdny do wykonania kaĪdej komendy RAM oraz objĊtoĞü

pami

Ċci uĪywanej przez kaĪdy z rejestrów, przyjmując przy tym pewne kryteria

wagowe. Rozwa

Īa siĊ nastĊpujące kryteria [1]:

x

równomierne kryterium wagowe oraz

x

logarytmiczne kryterium wagowe.

W przypadku równomiernego kryterium wagowego zak

áada siĊ, Īe kaĪda

komenda RAM potrzebuje na jej wykonanie jednej jednostki czasu, a ka

Īdy

rejestr wykorzystuje jedn

ą jednostkĊ pamiĊci.

Logarytmiczne kryterium wagowe jest oparte na za

áoĪeniu, Īe koszt wykonania

ka

Īdej komendy (jej waga) jest proporcjonalna do dáugoĞci operandów.

Rozwa

Īymy nastĊpującą funkcjĊ logarytmiczną okreĞloną na zbiorze liczb

ca

ákowitych

¬ ¼

¯

®

­

z



.

0

,

1

,

0

,

1

lg

i

i

i

i

l

Posta

ü tej funkcji uwzglĊdnia fakt, Īe dwójkowy zapis liczby caákowitej w

rejestrze wymaga

i

¬ ¼

1

lg



i

bitów (zapis

oznacza

log

).

lg

2

W celu wyznaczenia logarytmicznej z

áoĪonoĞci czasowej programów w jĊzyku

RAM, okre

Ğla siĊ wagi logarytmiczne dla poszczególnych typów operandów

oraz komend maszyny RAM. Wagi logarytmiczne

a

t

dla wszystkich trzech

typów operandów podano w tab.1.5, a wagi dla komend w tab.1.6.

Tab.1.5 Wagi logarytmiczne operandów.

- 23 -

Operand

a

Waga logarytmiczna

a

t

=

i

i

l

i

i

c

l

i

l



i

*

i

c

c

l

i

c

l

i

l





Tab.1.6 Wagi logarytmiczne komend.

Komenda

Waga logarytmiczna

LOAD

a

a

t

STORE

i

i

l

c

l



0

STORE

* i

i

c

l

i

l

c

l





0

ADD

a

a

t

c

l



0

SUB

a

a

t

c

l



0

MULT

a

a

t

c

l



0

DIV

a

a

t

c

l



0

READ

i

i

l

wejscie

l



READ

*i

i

c

l

i

l

wejscie

l





WRITE

a

a

t

JUMP

b

1

JGTZ

b

0

c

l

JZERO

b

0

c

l

HALT

1

Dla przyk

áadu wyznaczymy wagĊ logarytmiczną komendy ADD *i. Najpierw

jest okre

Ğlany stopieĔ trudnoĞci w dekodowaniu adresu operandu *i.

Przeg

áądanie liczby caákowitej i zajmuje czas

i

l

. Nast

Ċpnie naleĪy odczytaü

zawarto

Ğü

rejestru i pozwalaj

ącą ustaliü rejestr gdzie umieszczono

dodawan

ą liczbĊ, co wymaga czasu

i

c

i

c

l

. Wreszcie odczyt zawarto

Ğci

rejestru

, tj. samej adresowanej liczby wymaga czasu

i

c

c

i

c

i

c

c

l

. W sumie

odczyt dodawanej liczby zajmuje

i

c

c

i

c

l

l

i

l





jednostek czasu.

Poniewa

Ī komenda ADD*i dodaje liczbĊ caákowitą

i

c

c

do liczby ca

ákowitej

- 24 -

background image

0

c

w sumatorze, zatem waga dla ca

áej komendy jest równa sumie

i

c

c

l

i

c

l

i

l







c

l

0

.

¦

i

i

x

l

i

x

1



n

n

i

n

l

n

l

i

lg

1



|



,

lg

1

1

1

n

i

n

i

¦





n

n lg

2

n

n lg

|

n

l

n

Rozwa

Īymy teraz problem okreĞlania logarytmicznej záoĪonoĞci pamiĊciowej

programu RAM. Przyjmuje si

Ċ, Īe jest to suma

,

w której uwzg

áĊdniono wszystkie rejestry i (áącznie z sumatorem) biorące udziaá

w obliczeniach, a przez

oznaczono najwi

Ċkszą wartoĞü bezwzglĊdną liczby

ca

ákowitej, która w trakcie obliczeĔ pojawiáa siĊ w i-tym rejestrze.

Przyk

áad 1.6

Dokona

ü oceny záoĪonoĞci obliczeniowej programu obliczającego wartoĞü

funkcji z przyk

á.1.4.

Nietrudno zauwa

Īyü, Īe ze wzglĊdu na záoĪonoĞü czasową dominującym

fragmentem jest p

Ċtla zawierająca komendĊ MULT. Gdy komenda ta wykonuje

si

Ċ po raz i-ty, to sumator zawiera

, a rejestr 1 zawiera . W sumie komenda

MULT wykonuje si

Ċ

razy. Przyjmuj

ąc równomierne kryterium wagowe,

ka

Īda z komend MULT wymaga czasu równego jednej jednostce, a zatem na

wykonanie wszystkich tych komend potrzebny jest czas

i

n

n

n

O

. W przypadku

kryterium logarytmicznego i-ta komenda MULT zajmuje czas

a zatem czas wykonania wszystkich komend MULT jest równy

tzn.

O

.

Z

áoĪonoĞü pamiĊciowa jest wyznaczana wielkoĞcią liczb przechowywanych w

rejestrach od 0 do 3. Dla równomiernego kryterium wagowego z

áoĪonoĞü ta jest

pewn

ą staáą, a jej asymptotyczną granicĊ górną oznaczaü bĊdziemy jako

.

Poniewa

Ī najwiĊkszą z przechowywanych w rejestrach liczb jest

, a

1

O

n

n

, st

ąd w przypadku kryterium logarytmicznego otrzymujemy

z

áoĪonoĞü pamiĊciową

O

.

n

n lg

- 25 -

Nale

Īy zauwaĪyü, Īe dla tego programu równomierne kryterium wagowe jest

uzasadnione tylko w przypadku, je

Ğli liczba

mo

Īe byü zapisana w postaci

jednego s

áowa maszynowego. JeĞli tak nie jest, wówczas nawet logarytmiczna

z

áoĪonoĞü czasowa jest do pewnego stopnia nierealistyczna, gdyĪ zakáada ona,

Īe dwie liczby caákowite i i j mogą byü pomnoĪone w czasie

n

n

j

l

i

l

O



, co

nie jest bynajmniej oczywiste [1].

1.3.5 Z

áoĪonoĞü programów w pseudokodzie

Wprawdzie podstawowe miary z

áoĪonoĞci zostaáy przez nas okreĞlone w

terminach modelu obliczeniowego RAM, lecz w wielu przypadkach ocena
z

áoĪonoĞci konkretnego algorytmu moĪe byü dokonana na podstawie jego

zapisu w pseudokodzie.

Podobnie jak dla j

Ċzyka RAM, takĪe w tym przypadku istotny bĊdzie czas i

pami

Ċü potrzebne do wykonania komend pseudokodu. Sposób oceny záoĪonoĞci

czasowej algorytmu zapisanego w pseudokodzie ilustruje rozwa

Īany w [5]

przyk

áad sortowania przez wstawianie. Algorytm ten przedstawiono w

pierwszej kolumnie tab.1.7, a koszt wykonania poszczególnych instrukcji i
liczb

Ċ ich wykonaĔ odpowiednio w kolumnach drugiej i trzeciej.

Przyj

Ċto, Īe n oznacza liczbĊ elementów tablicy A, tzn. jest równe wartoĞci

atrybutu

> @

A

length

. Przez

t

oznaczono liczb

Ċ sprawdzeĔ warunku wejĞcia do

p

Ċtli dopóki w wierszu 5 dla pewnej wartoĞci j. W celu oceny záoĪonoĞci

obliczeniowej oblicza si

Ċ caákowity czas dziaáania algorytmu, który jest sumą

czasów dzia

áania poszczególnych instrukcji. JeĞli koszt (czas wykonania)

pewnej instrukcji powtarzanej

n

razy wynosi

c

, to ca

ákowity koszt wykonania

tej instrukcji wynosi

c

.

j

i

n

i

Tab.1.7 Wp

áyw instrukcji algorytmu sortowania przez wstawianie na jego záoĪonoĞü.

- 26 -

background image

Instrukcje

Koszt

Liczba
wykona

Ĕ

SORT-WSTAW (A)

1 dla j

m2 do length[A]

1

c

n

2

wykonuj { key

mA[j]

2

c

1



n

3

 Wstaw A[j] do posortowanego ciągu A[1..j-1].

0

1



n

4

i

mj-1

4

c

1



n

5

dopóki i>0 i A[i]>key

5

c

¦

n

j

j

t

2

6

wykonuj { A[i+1]

mA[i]

6

c

¦



n

j

j

t

2

1

7

i

mi-1 }

7

c

¦



n

j

j

t

2

1

8

A[i+1]

mkey }

8

c

1



n

Sumuj

ąc koszty wykonania poszczególnych instrukcji z tab.1.7 otrzymujemy

1

1

1

1

1

8

2

7

2

6

2

5

4

2

1























¦

¦

¦

n

c

t

c

t

c

t

c

n

c

n

c

n

c

n

T

n

j

j

n

j

j

n

j

j

.

Zauwa

Īmy, Īe w przypadku, gdy tablica wejĞciowa jest juĪ posortowana (tzw.

przypadek optymistyczny), mamy

1

j

t

dla

,

n

j

,...,

3

,

2

co daje minimalny czas dzia

áania algorytmu równy

.

1

1

1

1

8

5

4

2

8

5

4

2

1

8

5

4

2

1

c

c

c

c

n

c

c

c

c

c

n

c

n

c

n

c

n

c

n

c

n

M

































Jak wida

ü, wielkoĞü ta jest funkcją liniową wzglĊdem

n

.

W przypadku

pesymistycznym (tablica jest posortowana w porz

ądku

odwrotnym) mamy

j

t

j

dla

.

n

j

,...,

3

,

2

Z uwgl

Ċdnieniem zaleĪnoĞci

- 27 -

1

2

1

2





¦

n

j

n

n

j

oraz

¦





n

j

n

n

j

2

2

1

1

otrzymujemy

,

2

2

2

2

2

2

1

2

1

2

1

1

2

1

1

1

8

5

4

2

8

7

6

5

4

2

1

2

7

6

5

8

7

6

5

4

2

1

c

c

c

c

n

c

c

c

c

c

c

c

n

c

c

c

n

c

n

n

c

n

n

c

n

n

c

n

c

n

c

n

c

n

W









¸

¹

·

¨

©

§















¸

¹

·

¨

©

§









¸

¹

·

¨

©

§







¸

¹

·

¨

©

§





¸

¹

·

¨

©

§















n

co oznacza,

Īe pesymistyczna záoĪonoĞü czasowa tego algorytmu jest funkcją

kwadratow

ą wzglĊdem

. Stosuj

ąc poznaną notacjĊ asymptotyczną zapiszemy,

Īe pesymistyczny czas dziaáania algorytmu sortowania przez wstawianie wynosi

2

n

O

. W analizowanych dalej algorytmach zwykle b

Ċdziemy rozwaĪaü

przypadek pesymistyczny.

Pytania kontrolne

1. Poda

ü definicjĊ oraz charakterystyczne cechy algorytmu.

2. Okre

Ğliü nastĊpujące pojĊcia:

a) analiza algorytmów;
b) z

áoĪonoĞü obliczeniowa algorytmu;

c) poprawno

Ğü algorytmu;

d) asymptotyczna z

áoĪonoĞü czasowa;

e) rozmiar zadania.

3. Poda

ü definicjĊ i ilustracjĊ graficzną asymptotycznej granicy górnej.

4. Poda

ü definicjĊ i ilustracjĊ graficzną asymptotycznej granicy dolnej.

5. Wyja

Ğniü sens zapisu

f n

g n

4

.

6. Scharakteryzowa

ü model obliczeniowy RAM.

7. Omówi

ü komendy maszyny RAM.

- 28 -

background image

8. Wymieni

ü podstawowe konwencje zapisu algorytmów w pseudojĊzyku.

9. Okre

Ğliü nastĊpujące pojĊcia:

a) z

áoĪonoĞü pamiĊciowa;

b) operacja dominuj

ąca;

c) z

áoĪonoĞü czasowa;

d) z

áoĪonoĞü pesymistyczna;

e) z

áoĪonoĞü oczekiwana (Ğrednia).

10. Poda

ü formalną definicjĊ záoĪonoĞci pesymistycznej i záoĪonoĞci

oczekiwanej.

11. Na czym polegaj

ą: równomierne i logarytmiczne kryterium wagowe?

12. Poda

ü wagi logarytmiczne operandów w poleceniach maszyny RAM.

13. Poda

ü i uzasadniü wagi logarytmiczne komend LOAD, ADD, READ,

JGTZ, HALT.

14. Poda

ü i uzasadniü wagi logarytmiczne komend STORE, MULT, WRITE,

JUMP, JZERO.

Zadania

1. Wykaza

ü, Īe:

a)

; b)

6

2

n

O n

3

3

n

n

z 4

6

; c)

2

1

2

3

2

2

n

n

n



:

;

d) dla funkcji kwadratowej

f n

an

bn

c





2

, gdzie

i s

ą

sta

áymi oraz

, zachodzi

a b

,

c

a

! 0

f n

n

4

2

.

2. Zapisa

ü w jĊzyku maszyny RAM algorytm czytający liczby wejĞciowe, aĪ

do napotkania zera. Obliczy

ü sumĊ tych liczb i wypisaü wynik.

3. Zapisa

ü w pseudojĊzyku nastĊpujące algorytmy:

a)

Wyznaczanie najwi

Ċkszego wspólnego podzielnika dwóch liczb

(algorytm Euklidesa)

b)

Poszukiwanie maksymalnej warto

Ğci w tablicy jednowymiarowej

c)

Sortowanie przez selekcj

Ċ tablicy A záoĪonej z n elementów.

Znajdujemy najmniejszy element w tablicy i wstawiamy go na

- 29 -

pierwsze miejsce. Nast

Ċpnie znajdujemy drugi najmniejszy element i

wstawiamy go na drugie miejsce. W ten sposób post

Ċpujemy dla

wszystkich n elementów tablicy A.

4.

Dany jest nast

Ċpujący algorytm:

MAX
1 czytaj x
2 max

mx

3 dopóki x

z

0

4

wykonuj { je

Ğli x>max

5

to max

mx

6

czytaj x }

7 pisz max

a) Napisa

ü program w jĊzyku maszyny RAM realizujący ten algorytm

b) Okre

Ğliü záoĪonoĞü czasową i pamiĊciową programu RAM.

5.

Zapisa

ü w pseudojĊzyku algorytm, którego zadaniem jest sprawdzenie, czy

na wej

Ğciu pojawiáa siĊ jednakowa liczba jedynek i dwójek. Po

przeczytaniu 0, algorytm wypisuje 1, je

Ğli liczba jedynek i dwójek byáa

jednakowa i zatrzymuje si

Ċ. Zakáadamy, Īe oprócz 0, 1 i 2 na wejĞciu nie

mog

ą pojawiü siĊ Īadne inne symbole. Dla danego algorytmu wykonaü

tak

Īe nastĊpujące zadania:

a)

Napisa

ü program w jĊzyku maszyny RAM realizujący ten algorytm

b)

Okre

Ğliü záoĪonoĞü czasową i pamiĊciową programu RAM.

6.

Napisa

ü w pseudojĊzyku algorytm wyznaczania wartoĞci

dla podanej

liczby nieujemnej n, a nast

Ċpnie:

!

n

a) Napisa

ü program w jĊzyku maszyny RAM realizujący ten algorytm

b) Okre

Ğliü záoĪonoĞü czasową i pamiĊciową programu RAM.

Zadania 4,5,6 wykona

ü przyjmując zarówno równomierne, jak i

logarytmiczne kryterium wagowe.

- 30 -

background image

2

Struktury dynamiczne i rekursja

2.1 Wprowadzenie

Istnieje obszerna klasa elementarnych struktur danych, które wymagaj

ą staáej,

okre

Ğlanej w chwili ich utworzenia, wielkoĞci pamiĊci. Przykáadami są znane z

Pascala typy liczbowe, logiczne, tablice i

rekordy.

Tymczasem

w

rozwi

ązywaniu wielu problemów przydatne okazują siĊ takie struktury, których

chwilowa posta

ü i rozmiar zmieniają siĊ w trakcie przetwarzania, a pamiĊü dla

nich jest wydzielana i zwalniana w miar

Ċ potrzeby. Tego typu obiekty tworzą

klas

Ċ tzw. struktur dynamicznych, do których zaliczamy m.in.: listy, stosy,

kolejki i drzewa. Wiele struktur dynamicznych posiada charakter rekursywny,
st

ąd algorytmy operujące na takich strukturach wygodnie jest konstruowaü

stosuj

ąc rekursjĊ.

2.2 Listy

2.2.1

Definicje i reprezentacja pami

Ċciowa

Podstawow

ą strukturą dynamiczną jest lista. NajproĞciej listĊ moĪna okreĞliü

jako sko

Ĕczony ciąg elementów naleĪących do pewnego zbioru. JeĪeli jest to

ci

ąg:

, to list

Ċ czĊsto zapisuje siĊ w postaci:

n

e

e

e

,...,

,

2

1

n

e

e

e

...

2

1

.

Najprostsz

ą realizacją listy jest dynamiczna struktura pamiĊci pokazana na

rys.2.1.

e

1

na pierwszy

e

2

e

n

. . .

nil

element

wska

Ĩnik

Rys.2.1 Lista jednokierunkowa.

- 31 -

Elementarny sk

áadnik tej struktury skáada siĊ z dwóch pól, które moĪna

traktowa

ü jako odrĊbne komórki pamiĊci. Pierwsze z pól zawiera sam

pami

Ċtany element (jego zawartoĞü informacyjną), a drugie tzw. wskaĪnik

informuj

ący o poáoĪeniu nastĊpnego elementu w liĞcie. Wyjątkiem jest ostatni

sk

áadnik, gdzie w polu wskaĪnika umieszczono symbol nil, informujący, Īe w

tym miejscu nie wyst

Ċpuje wskaĨnik na Īaden element. WskaĨnik na pierwszy

element jest tak

Īe pamiĊtany w specjalnie do tego celu przeznaczonej zmiennej.

Struktura przedstawiona na rys.2.1 jest przyk

áadem tzw. listy jednokierunkowej,

w której pojedynczy sk

áadnik zawiera wskaĨnik tylko na element nastĊpny.

Najcz

ĊĞciej listĊ przedstawia siĊ w postaci nieco bardziej rozbudowanej

struktury okre

Ğlanej jako lista dwukierunkowa pokazana na rys.2.2.

e

1

head [L]

e

2

. . .

e

n

nil

nil

Rys.2.2 Lista dwukierunkowa.

Pojedynczy sk

áadnik listy dwukierunkowej zawiera pole informacyjne i dwa

pola wska

Ĩników: lewy wskazujący na poprzedni element oraz prawy

wskazuj

ący na element nastĊpny. ZauwaĪmy, Īe lewy wskaĨnik pierwszego

elementu i prawy wska

Ĩnik ostatniego elementu listy dwukierunkowej

zawieraj

ą symbol nil (nie wskazują na Īadne elementy). Taka organizacja list

sprawia,

Īe w odróĪnieniu od tablic, gdzie uĪywa siĊ indeksów, tutaj porządek

elementów jest okre

Ğlony za pomocą wskaĨników związanych z kaĪdym

elementem listy.

Przetwarzaj

ąc listy w pseudokodzie wprowadzimy specjalną zmienną typu lista

repezentuj

ącą strukturĊ z rys. 2.2. Przyjmuje siĊ, Īe wskaĨnik na pierwszy

element listy jest pami

Ċtany jako wartoĞü jej atrybutu o nazwie head.

Zak

áadając zatem, Īe L jest zmienną oznaczającą listĊ z rys.2.2, odwoáanie do

wska

Ĩnika na początek tej listy zapisujemy jako head[L]. Operacje na listach

cz

Ċsto wymagają uĪycia atrybutów takĪe dla pojedynczego elementu listy. JeĞli

przyj

ąü, Īe x jest elementem listy dwukierunkowej, to odwoáania do jego pól są

mo

Īliwe za pomocą nastĊpujących atrybutów (rys.2.3):

prev[x] - wska

Ĩnik na poprzedni element,

key[x] -

zawarto

Ğü informacyjna elementu,

next[x] - wska

Īnik na nastĊpny element.

- 32 -

background image

prev

next

key

e

i

Rys.2.3 Pola odpowiadaj

ące atrybutom elementu listy.

Wprowadzony wcze

Ğniej symbol nil moĪna takĪe traktowaü jako „wskaĨnik

pusty”, st

ąd head[L]=nil oznacza, Īe lista L jest pusta (nie zawiera Īadnych

elementów). Z kolei spe

ánienie równoĞci prev[x]=nil oznacza, Īe element x nie

ma poprzednika, je

Ğli natomiast next[x]=nil, to element x nie ma nastĊpnika.

2.2.2

Podstawowe operacje na listach

Poszukiwanie elementu w li

Ğcie

Rozwa

Īymy funkcjĊ LISTA-POSZ z parametrami L i k, wyznaczającą pierwszy

napotkany element listy L, którego pole key[x] (pole klucza) ma warto

Ğü k. W

wyniku funkcja zwraca wska

Ĩnik na ten element, a jeĞli elementu nie

znaleziono, jest zwracana warto

Ğü nil. Przykáadowy zapis funkcji LISTA-POSZ

przedstawiono w postaci kodu K.2.1.

K.2.1

LISTA-POSZ(L,k)
1 x

m

head[L]

2 dopóki x

znil i key[x] zk

3

wykonuj

x

m

next[x]

4 zwró

ü x

Poszukiwanie w tym algorytmie odbywa si

Ċ metodą przeglądania kolejnych

elementów listy L. Na pocz

ątku zmiennej x jest nadawana wartoĞü wskaĪnika na

pocz

ątek listy. NastĊpnie w pĊtli dopóki x przyjmuje wartoĞci wskaĨników na

kolejne elementy listy, a

Ī do znalezienia poszukiwanego elementu lub

wyczerpania elementów listy. Je

Ğli liczbĊ elementów listy oznaczyü przez n, to

pesymistyczny czas dzia

áania tego algorytmu wynosi O(n), poniewaĪ w

najgorszym przypadku oka

Īe siĊ konieczne sprawdzenie wszystkich elementów

listy.

- 33 -

Wstawianie elementu do listy

Kod K.2.2 zawiera procedur

Ċ LISTA-WSTAW z parametrami L i x, która

do

áącza nowy element x na początek listy L.

K.2.2

LISTA-WSTAW(L,x)
1 next[x]

m

head[L]

2 je

Ğli head[L]

znil

3

to

prev[head[L]]

m

x

4 head[L]

m

x

5 prev[x]

m

nil

Wstawianie nowego elementu x na pocz

ątek listy niepustej listy L zilustrowano

na rys.2.4.

nil

e

1

head [L]

. . .

e

n

nil

nil

x

e

dod

e

1

head [L]

. . .

e

n

nil

nil

x

e

dod

e

1

head [L]

. . .

e

n

nil

x

e

dod

e

1

head [L]

. . .

e

n

nil

x

e

dod

a)

e

1

head [L]

. . .

e

n

nil

x

e

dod

b)

c)

e)

d)

Rys.2.4 Wstawianie nowego elementu do listy.

- 34 -

background image

Przed wykonaniem procedury wstawiania head[L] jest wska

Ĩnikiem na

pocz

ątek listy, a x wskazuje na nowy element (rys.2.4a). Pierwszą operacją

wykonywan

ą w linii 1 kodu K.2.2 jest nadanie wskaĨnikowi next[x] wartoĞci

head[L], co prowadzi do sytuacji pokazanej na rys.2.4b. Kolejne operacje
odpowiadaj

ące liniom 3, 4 i 5 algorytmu przedstawiono odpowiednio na

rys.2.4c, 2.4d i 2.4e.

Czas dzia

áania procedury LISTA-WSTAW nie zaleĪy od liczby elementów w

li

Ğcie L, a zatem moĪe byü zapisany jako O(1).

Usuwanie elementu z listy

Wprowadzimy procedur

Ċ LISTA-USUē(L,x) (kod K.2.3), która usuwa z listy L

element x.

K.2.3

LISTA-USU

ē(L,x)

1 je

Ğli prev[x]

znil

2

to

next[prev[x]]

m

next[x]

3

inaczej

head[L]

m

next[x]

4 je

Ğli next[x]

znil

5

to

prev[next[x]]

m

prev[x]

Wprawdzie procedura LISTA-USU

ē dziaáa w czasie

O(1), jednak

pesymistyczny koszt usuni

Ċcia elementu x, dla którego zamiast wskaĨnika

znana by

áaby tylko zawartoĞü informacyjna (key[x]) wynosi O(n). Wynika to z

konieczno

Ğci uprzedniego znalezienia elementu x, co wymagaáoby uĪycia

funkcji LISTA-POSZ (kod K.2.1).

Przedstawienie list za pomoc

ą tablic

Reprezentacja list w pami

Ċci jest moĪliwa takĪe bez uĪycia wskaĨników. Jeden

ze sposobów polegaj

ący na uĪyciu tablic jednowymiarowych pokazano na

rys.2.5.

- 35 -

9

head [L]

nil

1

nil

16

4

3

4

5

nil

1

2

1

2

3

4

5

6

7

8

2

16

7

5

9

nil

next

key

a)

b)

prev

Rys.2.5 Reprezentowanie listy przy pomocy tablic jednowymiarowych.

Rysunek 2.5a przedstawia list

Ċ (9 16 4 1) jako strukturĊ zbudowaną przy

pomocy wska

Ĩników. Ta sama lista moĪe byü przedstawiona za pomocą trzech

tablic: next, key i prev w sposób pokazany na rys.2.5b. Tablica key zawiera
warto

Ğci kluczy (czĊĞü informacyjną) elementów listy, a wskaĨniki są

reprezentowane przez tablice next i prev. Zatem dla pewnego indeksu i warto

Ğci

prev[i], key[i] oraz next[i] le

Īące w kolumnie i okreĞlają pojedynczy element

listy. Na przyk

áad element listy o kluczu 16 posiada poprzednika, którym jest

element przechowywany w tablicy key z indeksem 7. Jest to element o warto

Ğci

klucza 9.

W podanym przyk

áadzie do reprezentacji list uĪyto trzech tablic. Innym

mo

Īliwym sposobem jest uĪycie do tego celu tylko jednej tablicy.

2.3 Stosy i kolejki

Stosy i kolejki reprezentuj

ą grupĊ obiektów, okreĞlanych jako struktury z

ograniczonym dost

Ċpem. Ograniczenie polega na tym, Īe tryb dodawania i

usuwania elementów jest z góry ustalony i charakterystyczny dla danej
struktury.

2.3.1 Stosy

Struktura nazywana stosem posiada ustalony element nazywany wierzcho

ákiem,

który jest jedynym dost

Ċpnym w danej chwili jej skáadnikiem. Sytuacja taka

oznacza,

Īe dowolna operacja usuwania ze stosu moĪe dotyczyü tylko jego

aktualnego wierzcho

áka. Ponadto dodanie nowego elementu do stosu jest

mo

Īliwe tylko przez umieszczenie tego elementu na „szczycie” stosu, tak aby

- 36 -

background image

sta

á siĊ on nowym wierzchoákiem. Mówimy, Īe elementy stosu są obsáugiwane

wed

áug porządku LIFO (Last In First Out), co oznacza „ostatni przyszedá,

pierwszy wyszed

á”.

Sugestywn

ą ilustracją stosu moĪe byü pewna liczba talerzy poukáadanych jeden

na drugim. Przy dodawaniu kolejnego talerza

najbardziej

rozs

ądnym

post

Ċpowaniem jest umieszczenie go na samej górze. W przypadku pobierania

talerza, zdejmujemy ten, który znajduje si

Ċ na szczycie, tj. zostaá poáoĪony jako

ostatni.

Jako struktury reprezentuj

ącej stos w pamiĊci moĪna uĪyü tablicy

jednowymiarowej

. Dla tej tablicy okre

Ğlimy atrybut top[S] podający

numer (indeks) elementu ostatnio umieszczonego na stosie. Stos sk

áada siĊ

zatem z elementów

>

n

S ..

1

> @

@

> @

> @

>

@

S

top

S

,...,

2

S

S ,

1

, gdzie

> @

1

S

oznacza element na dnie

stosu, a

> @

>

@

S

top

S

> @

S

top

jest elementem na wierzcho

áku stosu (rys.2.6). Przyjmuje

si

Ċ, Īe jeĞli

, to stos jest pusty i próba pobrania elementu z takiego

stosu spowoduje komunikat o b

áĊdzie „niedomiaru“.

0

Rys.2.6 Stos.

S[1]

S[2]

S[3]

S[4]

15

top[S]=4

6

2

9

S[top[S]]= 9
S[1]= 15

Tradycyjnie operacj

Ċ umieszczania na stosie nazywa siĊ PUSH, a operacjĊ

zdejmowania ze stosu – POP. Pos

áugując siĊ zdefiniowaną tutaj „tablicową“

reprezentacj

ą stosu operacjĊ umieszczania elementu x na stosie S moĪna napisaü

w postaci prostej procedury (kod K.2.4).

K.2.4

PUSH(S,x)
1 top[S]

m

top[S]+1

2 S[top[S]]

m

x

Kod K.2.5 zawiera procedur

Ċ zdejmowania ze stosu. Procedura ta wykorzystuje

funkcj

Ċ STOS-PUSTY(S), sprawdzającą czy stos jest pusty (kod K.2.6)

- 37 -

K.2.5

POP(S)
1 je

Ğli STOS-PUSTY(S)

2

to

b

áąd „niedomiar”

3

inaczej

{top[S]

m

top[S]-1

4 { zwró

ü S[top[S]+1]}

K.2.6

STOS-PUSTY(S)
1 je

Ğli top[S]=0

2

to

TRUE

3

inaczej

FALSE

Nale

Īy zauwaĪyü, Īe uĪycie procedury PUSH wymaga podania dwóch

argumentów, podczas gdy w przypadku procedury POP wystarczy tylko jeden
(identyfikator stosu). Wynika to st

ąd, Īe pobieranym elementem stosu moĪe byü

w danej chwili tylko jego wierzcho

áek, tzn. element S[top[S]].

2.3.2 Kolejki

Poj

Ċciem kolejka okreĞla siĊ strukturĊ z ograniczonym dostĊpem, dla której

okre

Ğlono początek i koniec. Prostą ilustracją moĪe byü kolejka osób do kasy, w

której nowe osoby maj

ą prawo ustawiü siĊ na koĔcu, a obsáugiwana jest zawsze

osoba z pocz

ątku. Tak jak w przypadku stosu, procedura obsáugi kolejki ma

ogólnie przyj

Ċtą nazwĊ. Mówimy, Īe elementy kolejki są obsáugiwane wedáug

porz

ądku FIFO (First In First Out), co oznacza „pierwszy przyszedá, pierwszy

wyszed

á”

Podobnie jak dla stosu przyjmiemy tablicow

ą implementacjĊ kolejki zakáadając,

Īe elementy kolejki są pamiĊtane w tablicy jednowymiarowej

Q

.

Pos

áuĪymy siĊ nastĊpującymi atrybutami tablicy Q (rys.2.7):

> @

n

..

1

head[Q]

- indeks elementu znajduj

ącego siĊ na początku kolejki (gáowa),

tail[Q]

- indeks pierwszego wolnego elementu na ko

Ĕcu kolejki (ogon).

Q

head[Q]=7

15

1

2

3

4

5

6

7

8

9

10

11

12

6

9

8

4

13

14

15

tail[Q]=12

Q[7]=15

Rys.2.7 Kolejka.

W procedurach wstawiania i usuwania elementu z kolejki b

Ċdziemy zakáadaü,

Īe tablica

Q

jest cykliczna, tzn. po elemencie

>

n

..

1

@

> @

n

Q

nast

Ċpuje element

- 38 -

background image

> @

1

Q

. Na pocz

ątku przyjmuje siĊ

> @

> @

1

Q

tail

Q

head

. Spe

ánienie warunku

oznacza,

Īe kolejka jest pusta. JeĞli natomiast zachodzi

równo

Ğü

> @

> @

Q

tail

Q

> @

head

> @

1



Q

tail

Q

head

, to kolejka jest pe

ána. Przyjmując tablicową

reprezentacj

ą kolejki operacjĊ umieszczania nowego elementu x w kolejce Q

mo

Īna napisaü w postaci procedury ENQUEUE(Q,x) (kod K.2.7), a operacjĊ

usuwania z kolejki jako funkcj

Ċ DEQUEUE(Q) (kod K.2.8).

1

2



2



7

6

4



5

7

6

4

8

9





K.2.7

ENQUEUE(Q,x)
1 Q[tail[Q]]

m

x

2 je

Ğli tail[Q]= length[Q]

3

to tail[Q]

m

1

4

inaczej tail[Q]

m

tail[Q]+1

K.2.8

DEQUEUE(Q)
1 x

m

Q[head[Q]]

2 je

Ğli head[Q]= length[Q]

3

to head[Q]

m

1

4

inaczej head[Q]

m

head[Q]+1

5 zwró

ü x

Obie procedury dzia

áają w czasie O(1). PrzyjĊto takĪe, Īe w przypadku

dodawania nowego elementu kolejka nie jest pe

ána, a w przypadku, usuwania,

kolejka nie jest pusta.

2.4 Obliczanie warto

Ğci wyraĪeĔ z wykorzystaniem stosu

Zastosowanie stosu mo

Īna pokazaü na przykáadzie obliczania wartoĞci prostych

wyra

ĪeĔ arytmetycznych, w których wystĊpują tylko liczby caákowite 0...9,

nawiasy ‘(‘ i ‘)' oraz operacje dodawania i mno

Īenia. Do klasy takich wyraĪeĔ

nale

Īą np.:

,

7

1

,

8

9



, itp.

Stos okazuje si

Ċ byü wygodnym miejscem do pamiĊtania wyników poĞrednich

w takich obliczeniach. Na przyk

áad wartoĞü wyraĪenia

5

mo

Īe byü wyznaczona w wyniku ciągu operacji na stosie pokazanych na

rys.2.8.

- 39 -

a)

ZERUJ(S) PUSH(S,5) PUSH(S,9)

5

5

9

b)

c)

PUSH(S,8)

PUSH(S,POP(S)+POP(S))

5

5

17

d)

e)

9

8

PUSH(S,4)

PUSH(S,POP(S)*POP(S))

5

5

17

f)

g)

17

4

4

6

PUSH(S,POP(S)*POP(S))

PUSH(S,6)

5

5

408

17

24

i)

h)

PUSH(S,7)

5

5

415

j)

k)

408

7

PUSH(S,POP(S)*POP(S))

PUSH(S,POP(S)+POP(S))

2075

l)

Rys.2.8 U

Īycie stosu do wyznaczania wartoĞci wyraĪenia.

Podczas wykonywania dowolnej operacji odpowiednie operandy s

ą pobierane

ze stosu, a wynik jest umieszczany tak

Īe na stosie. ZauwaĪmy, Īe taki sposób

wykonywania oblicze

Ĕ wymaga, aby operandy byáy umieszczone na stosie,

zanim zostanie napotkany znak operacji. Po

Īądane byáoby zatem, aby

wyra

Īenie zostaáo wczeĞniej zapisane w pewnej postaci poĞredniej, w której

operandy wyst

Ċpują zawsze przed znakiem operacji. Dla naszego wyraĪenia jest

to zatem ci

ąg znaków:

5 9 8 + 4 6 * * 7 + *.

Taki zapis wyra

ĪeĔ jest nazywany zapisem postfiksowym albo odwrotnym

zapisem polskim. W odró

Īnieniu od zapisu postfiksowego, tradycyjny zapis

matematyczny, gdzie operandy s

ą oddzielone znakiem operacji bĊdziemy

nazywa

ü zapisem infiksowym. Istotną wáaĞciwoĞcią zapisu postfiksowego jest

tak

Īe to, Īe nie wymaga on nawiasów. Pomimo braku nawiasów wyraĪenia są

obliczane od lewej strony do prawej we w

áaĞciwej kolejnoĞci. Notacja

- 40 -

background image

postfiksowa okazuje si

Ċ byü idealnym zapisem poĞrednim dla wyraĪeĔ

arytmetycznych, które maj

ą byü obliczane za pomocą stosu. Mechanizm ten

mo

Īna zastosowaü w kalkulatorach i w komputerowej realizacji jĊzyków

programowania.

Naszym zadaniem jest opracowanie algorytmu, który przekszta

áca tradycyjny

zapis infiksowy w odwrotny zapis polski. Wcze

Ğniej jednak przedstawimy

pomocnicz

ą procedurĊ LISTA-ODWR(L) (kod K.2.9), która realizuje prostą,

ale przydatn

ą operacjĊ odwracania kolejnoĞci elementów w liĞcie L.

K.2.9

LISTA-ODWR(L)
1 x

m

head[L]

2 head[LR]

m

nil

3 dopóki x

znil

4 wykonuj { LISTA-WSTAW(LR,x)
5

x

m

next[x] }

6 head[L]

m

head[LR]

Procedura LISTA-ODWR(L) korzysta ze zmiennej roboczej LR, która jest typu
lista i s

áuĪy do budowania listy odwróconej. Wykorzystuje siĊ przy tym

przedstawion

ą wczeĞniej procedurĊ wstawiania nowego elementu do listy. Po

zbudowaniu listy odwróconej wska

Īnik na jej początek staje siĊ wartoĞcią

wska

Ĩnika na początek listy L (linia 6 w kodzie K.2.9). Kolejne etapy

odwracania przyk

áadowej listy (9 16 4) za pomocą procedury LISTA-

ODWR(L) pokazano na rysunku 2.9.

- 41 -

9

head [L]

nil

16

4

a)

head [LR]=nil

nil

9

head [L]

nil

16

4

b)

nil

9

head [L]

nil

16

4

d)

nil

9

head [LR]

nil

nil

4

head [LR]

nil

16

9

nil

9

head [L]

nil

16

4

c)

nil

16

head [LR]

nil

9

nil

9

head [L]

nil

16

4

e)

nil

4

head [LR]

nil

16

9

nil

Rys.2.9 Odwracanie listy.

Procedura odwracania listy zostanie wykorzystana w opisanym dalej
algorytmie INF-PSF przej

Ğcia od zapisu infiksowego do zapisu

postfiksowego. Przyk

áadowe wyraĪenie infiksowe jest przeksztaácane na

wyra

Īenie postfiksowe w sposób pokazany na rys.2.10.

- 42 -

background image

tablica TWE

(

1

3

4

2

2

1

+

6

7

5

3

*

)

TWE,LWY

INF-PSF(

)

( 2 1 + 3 * )

lista LWY

Rys.2.10 Przej

Ğcie z zapisu infiksowego na postfiksowy.

Wej

Ğcie algorytmu stanowi tablica TWE zawierająca pojedyncze znaki

zadanego wyra

Īenia infiksowego, a wynik (odwrotny zapis polski) jest

otrzymywany w postaci listy wyj

Ğciowej LWY. Algorytm w postaci

procedury INF-PSF z parametrami TWE i LWY zawiera kod K.2.10.

K.2.10

INF-PSF(TWE, LWY)
1

top[STOS]

m

0

2

head[LWY]

m

nil

3

i

m

1

4

powtarzaj

5

je

Ğli TWE[i] jest liczb

ą

6

to

{ key[x]

m

TWE[i]

7

LISTA-WSTAW(LWY, x) }

8

inaczej je

Ğli TWE[i]=”+” lub TWE[i]=”*”

9

to

PUSH(STOS, TWE[i])

10

inaczej je

Ğli TWE[i]=”)”

11

to

{ key[x]

m

POP(STOS)

12

LISTA-WSTAW(LWY, x) }

13

i

m

i+1

14

a

Ī_do i>length[TWE]

15

je

Ğli STOS-PUSTY(STOS)

16

to

LISTA-ODWR(LWY)

17

inaczej

{ key[x]

m

POP(STOS)

18

LISTA-WSTAW(LWY,x)

19 LISTA-ODWR(LWY) }

Algorytm analizuje kolejne elementy tablicy wej

Ğciowej TWE. JeĞli kolejny

element tej tablicy zawiera operand (liczb

Ċ), wówczas jest ona niezwáocznie

umieszczana w li

Ğcie wyjĞciowej. Operacja ta jest realizowana w liniach 6 i 7 i

- 43 -

wymaga u

Īycia zmiennej pomocniczej x, która staje siĊ wskaĨnikiem do

do

áączanego elementu listy. Znaki operacji są tymczasowo umieszczane na

stosie (linia 9). Lewe nawiasy s

ą ignorowane, a napotkanie prawego nawiasu

oznacza,

Īe oba operandy dla operacji wykonywanej na danym poziomie

zagnie

ĪdĪenia obliczeĔ juĪ wystąpiáy i naleĪy pobraü ze stosu odpowiadający

im znak operacji oraz do

áączyü go do listy wyjĞciowej (linie 11 i 12). Dla

uproszczenia zak

áada siĊ, Īe na danym poziomie zagnieĪdĪenia wystĊpują

dok

áadnie dwa operandy poáączone znakiem operacji. NaleĪy takĪe zaznaczyü,

Īe algorytm nie zajmuje siĊ ewentualnymi báĊdami w wyraĪeniach.

Linie od 15 do 19 zawieraj

ą polecenia generujące koĔcową postaü wyniku.

Warto zauwa

Īyü, Īe lista wynikowa jest odwracana za pomocą procedury

LISTA-ODWR(LWY), dzi

Ċki czemu operandy i znaki operacji w wyraĪeniu

postfiksowym pojawiaj

ą siĊ w naturalnym porządku „od lewej do prawej”.

Jak ju

Ī wspomniano, gáównym powodem, dla którego stosujemy zapis

postfiksowy jest to,

Īe wartoĞü tak zapisanego wyraĪenia moĪe byü áatwo

obliczona przy pomocy stosu. Algorytm wykonuj

ący takie obliczenie nie jest

zbyt skomplikowany, a przy jego opracowaniu pomocn

ą moĪe okazaü siĊ

analiza przyk

áadu obliczania wyraĪenia 5 9 8 + 4 6 * * 7 + * z rys.2.8.

2.5 Grafy

2.5.1

Grafy skierowane i nieskierowane

Zdefiniujemy podstawowe poj

Ċcia oraz sposób reprezentowania w pamiĊci dla

popularnej klasy struktur nazywanych grafami.

Definicja 2.1

Grafem nazywamy par

Ċ zbiorów

E

V ,

G

, gdzie V jest sko

Ĕczonym zbiorem

wierzcho

áków, a E jest zbiorem krawĊdzi. Przykáady grafów pokazano na

rys.2.11.

- 44 -

background image

a)

b)

1

2

4

5

1

2

5

4

3

3

6

Rys.2.11 Przyk

áady grafów: a) graf skierowany, b) graf nieskierowany.

Na rys.2.11a przedstawiono graf okre

Ğlany jako nieskierowany, dla którego

^

`

5

,

4

,

3

,

2

,

1

V

, a

^

`

5

,

4

,

4

,

3

,

5

,

2

,

4

,

2

,

3

,

2

,

5

,

1

,

2

,

1

E

.

Zbiór kraw

Ċdzi E takiego grafu jest zatem zbiorem par

v

u,

, gdzie

u

.

Zauwa

Īmy, Īe pary

i

V

v



,

v

u,

v

u,

oznaczaj

ą tĊ samą krawĊdĨ, a ponadto

(nie wyst

Ċpują pĊtle, tj. krawĊdzie prowadzące do tego samego wierzchoáka).

Zbiór kraw

Ċdzi E w grafie nieskierowanym jest zbiorem nieuporządkowanych

par wierzcho

áków

. Kraw

ĊdĨ

v

u

z

v

u,

v

u,

jest okre

Ğlana jako incydentna z

wierzcho

ákami u i v.

Na rys.2.11b pokazano graf skierowany, w którym

^

`

6

,

5

,

4

,

3

,

2

,

1

V

, a

^

`

6

,

6

,

4

,

5

,

2

,

4

,

6

,

3

,

5

,

3

,

5

,

2

,

4

,

1

,

2

,

1

E

.

Zauwa

Īmy, Īe w grafie skierowanym mogą wystąpiü pĊtle do tego samego

wierzcho

áka, a krawĊdĨ

v

u,

jest tutaj okre

Ğlana, jako wychodząca

z wierzcho

áka u i wchodząca do wierzchoáka v.

Je

Ğli

jest kraw

Ċdzią grafu

v

u,

E

V ,

G

, to mówimy,

Īe wierzchoáek u jest

s

ąsiedni do wierzchoáka v. Fakt ten dla grafu skierowanego moĪna zapisaü jako

v

u

o

.

Liczb

Ċ wszystkich wierzchoáków grafu oznaczymy symbolem

V

, a liczb

Ċ

kraw

Ċdzi symbolem

E

.

- 45 -

Definicja 2.2

Stopniem wierzcho

áka w grafie nieskierowanym nazywamy liczbĊ incydentnych

z nim kraw

Ċdzi. W przypadku wierzchoáków grafu skierowanego operuje siĊ

poj

Ċciami stopnia wyjĞciowego (liczba krawĊdzi wychodzących) i stopnia

wej

Ğciowego (liczba krawĊdzi wchodzących).

Definicja 2.3

ĝcieĪką (drogą) dáugoĞci k z wierzchoáka

do wierzcho

áka

u

uc

w grafie

nazywamy ci

ąg wierzchoáków

E

V

G

,

k

v

v

v

,...,

,

1

0

, takich,

Īe

i

oraz

dla

0

v

u

k

v

u

c

E

v

v

i

i





,

1

k

i

,...,

1

.

Definicja 2.4

Cyklem w grafie skierowanym nazywamy

ĞcieĪkĊ

k

v

v

v

,...,

,

1

0

zawieraj

ącą co

najmniej jedn

ą krawĊdĨ, dla której

k

v

v

0

.

Definicja 2.5

Cyklem w grafie nieskierowanym nazywamy

ĞcieĪkĊ

k

v

v

v

,...,

,

1

0

, dla której

, wierzcho

áki

s

ą róĪne i

.

k

v

v

0

k

v

v

v

,...,

,

2

1

2

t

k

Graf nie zawieraj

ący cykli nazywamy acyklicznym.

Definicja 2.6

Graf nieskierowany jest spójny je

Ğli kaĪda para wierzchoáków jest poáączona

ĞcieĪką. W przypadku grafu skierowanego istnieje pojĊcie silnej spójnoĞci,
które oznacza,

Īe kaĪde dwa wierzchoáki są osiągalne jeden z drugiego.

2.5.2

Sposoby reprezentowania grafów

Istniej

ą dwa podstawowe sposoby reprezentowania grafów. Są to:

1. Listy s

ąsiedztwa

2. Macierze

s

ąsiedztwa.

Przedstawienie grafów za pomoc

ą list sąsiedztwa

- 46 -

background image

Jako struktur

Ċ reprezentującą graf

E

V

G

,

rozwa

Īamy tablicĊ Adj rozmiaru

V

, której elementami s

ą listy odpowiadające wierzchoákom z V. Dla kaĪdego

wierzcho

áka

list

Ċ

V

u



> @

u

Adj

tworz

ą wszystkie wierzchoáki v takie, Īe

. Listy s

ąsiedztwa dla grafów z rys.2.11a i 2.11b przedstawiono

odpowiednio na rys.2.12a i 2.12b.

E

v



u,

a)

b)

1

2

3

4

2

1

2

2

3

2

nil

5

5

4

5

5

4

1

3

nil

4

nil

1

2

3

4

2

5

6

2

5

4

4

nil

5

nil

nil

nil

nil

6

6

nil

nil

nil

Rys.2.12 Listy s

ąsiedztwa.

Zalet

ą reprezentacji listowej jest to, Īe umoĪliwia ona przedstawienie w zwarty

sposób grafów rzadkich, dla których

2

V

E



. Przy takiej reprezentacji

rozmiar wymaganej pami

Ċci wynosi

E

V

O

E

V

O



,

max

.

Przedstawienie grafów za pomoc

ą macierzy sąsiedztwa

Graf

G

mo

Īe byü reprezentowany takĪe przez tablicĊ dwuwymiarową,

sk

áadającą siĊ wyáącznie z zer i jedynek, nazywaną macierzą sąsiedztwa.

Zak

áadamy wtedy, Īe wierzchoáki grafu są ponumerowane od 1 do

E

V ,

V

. Macierz

s

ąsiedztwa jest tablicą dwuwymiarową

ij

a

A

V

j

V

i

d

d

d

d

1

,

1

, gdzie

¯

®

­



razie.

przeciwnym

w

0

E,

,

jesli

1

j

i

a

ij

Macierze reprezentuj

ące grafy z rys.2.11a i 2.11b przedstawiono odpowiednio

na rys.2.13a i 2.13b.

- 47 -

a)

b)

1

2

3

4

1

2 3

4

0

0

0

1

1

1

1

1

1

0

1

1 0

0

0

0

5

5

1

1

0

1

1

0 1

1

0

1

2

3

4

1

2 3

4

0

1

0

1

0

0

0

0

0

0

1

0 0

0

0

0

5

5

0

1

1

0

0

0 1

0

0

0

0 0

0

0

0

0

1

0

0

1

6

6

Rys.2.13 Macierze s

ąsiedztwa.

Taka reprezentacja jest korzystna wówczas, gdy graf jest „g

Ċsty” tzn,

E

jest

bliskie

2

V

lub gdy wyst

Ċpuje potrzeba szybkiego stwierdzania, czy istnieje

kraw

ĊdĨ áącząca dwa zadane wierzchoáki. Rozmiar wymaganej pamiĊci wynosi

2

V

O

. Dla grafu nieskierowanego

pami

Ċü moĪna zaoszczĊdziü,

wykorzystuj

ąc symetrycznoĞü macierzy sąsiedztwa.

2.6 Drzewa

2.6.1 Definicje

Zdefiniujemy podstawowe poj

Ċcia odnoszące siĊ obszernej klasy struktur

danych okre

Ğlanych jako drzewa.

Definicja 2.7

Drzewem zorientowanym (skierowanym) nazywamy skierowany graf acykliczny
spe

ániający nastĊpujące trzy warunki:

1. Istnieje dok

áadnie jeden wierzchoáek, do którego nie dochodzi Īadna

kraw

ĊdĨ. Wierzchoáek ten nazywamy korzeniem drzewa.

2. Dla dowolnego wierzcho

áka v w drzewie istnieje droga prowadząca od

korzenia do tego wierzcho

áka i jest to droga jedyna.

3. Ka

Īdy wierzchoáek nie bĊdący korzeniem ma dokáadnie jedną krawĊdĨ

wchodz

ącą do niego.

- 48 -

background image

Dla drzewa zorientowanego z rys.2.14 zbiorem wierzcho

áków jest

, a zbiorem kraw

Ċdzi

^

7

,

6

,

5

,

4

,

3

,

2

,

1

V

`

^

`

7

,

3

6

,

2

,

5

,

2

,

4

,

2

,

3

,

1

,

2

,

1

E

.

Korzeniem jest wierzcho

áek 1.

Cz

Ċsto rozwaĪa siĊ drzewa niezorientowane, tj. takie, w których istnieje droga

nie tylko od korzenia do pewnego w

Ċzáa lecz droga w obu kierunkach.

Definicja 2.8

Drzewem niezorientowanym nazywamy graf nieskierowany, który jest:

1. Spójny tj. istnieje droga pomi

Ċdzy dwoma dowolnymi wierzchoákami.

2. Acykliczny.
3. Posiada

wyró

Īniony wierzchoáek nazywany korzeniem

Drzewa niezorientowane b

Ċdziemy przedstawiaü graficznie w sposób pokazany

na rys. 2.15.

1

2

6

4

3

7

5

1

2

6

4

3

7

5

Rys.2.14 Drzewo zorientowane.

Rys.2.15 Drzewo niezorientowane.

W przypadku drzew wierzcho

áki czĊsto nazywa siĊ wĊzáami.

Definicja 2.9

Je

Ğli rozwaĪyü krawĊdĨ

E

w

v



,

w drzewie zorientowanym, to w

Ċzeá v jest

nazywany rodzicem wierzcho

áka w, a wĊzeá w jest nazywany synem

wierzcho

áka v. PojĊcie rodzica i syna ma zastosowanie takĪe dla drzew

niezorientowanych. W tym przypadku tak

Īe rozwaĪa siĊ krawĊdĨ

, z

tym,

Īe wĊzeá v jest wĊzáem poáoĪonym o jeden poziom wyĪej w strukturze

drzewa ni

Ī wĊzeá w.

E

w

v



,

Definicja 2.10

Je

Īeli w drzewie zorientowanym istnieje droga prowadząca od wĊzáa v do wĊzáa

w, to w

Ċzeá w nazywamy potomkiem wĊzáa v, a wĊzeá v nazywamy przodkiem

w

Ċzáa w. Dla drzewa niezorientowanego naleĪy zaznaczyü, Īe wĊzeá v jest

po

áoĪony wyĪej w strukturze drzewa niĪ wĊzeá w.

- 49 -

Definicja 2.11

Pewien w

Ċzeá v wraz ze wszystkimi jego potomkami nazywamy poddrzewem.

W

Ċzeá v jest wtedy okreĞlany jako korzeĔ tego poddrzewa.

Definicja 2.12

W

Ċzeá nie posiadający potomków nazywamy liĞciem.

Definicja 2.13

G

áĊbokoĞcią wĊzáa nazywamy dáugoĞü drogi od korzenia do tego wĊzáa.

Definicja 2.14

Wysoko

Ğü wĊzáa oznacza maksymalną dáugoĞü drogi od tego wĊzáa do liĞcia.

Wysoko

Ğcią drzewa jest zatem wysokoĞü jego korzenia.

W wielu zastosowaniach przydatne s

ą tzw. drzewa uporządkowane.

Definicja 2.15

Drzewem uporz

ądkowanym nazywamy drzewo, w którym zbiór synów kaĪdego

w

Ċzáa jest uporządkowany. W graficznej reprezentacji drzew uporządkowanych

b

Ċdziemy zakáadaü, Īe synowie kaĪdego wĊzáa są uporządkowani od lewej

strony do prawej.

2.6.2 Drzewa binarne

Wa

Īną klasĊ drzew uporządkowanych stanowią drzewa binarne.

Definicja 2.16

Drzewem binarnym nazywamy drzewo spe

ániające dwa warunki:

i. Ka

Īdy wĊzeá posiada co najwyĪej dwóch synów

ii. W

Ğród synów kaĪdego wĊzáa da siĊ wyróĪniü lewy i prawy.

Przyk

áad drzewa binarnego przedstawia rys. 2.16a, a prosty sposób

reprezentowania tego drzewa za pomoc

ą tablic pokazano na rys. 2.16b.

- 50 -

background image

1

2

4

3

6

7

8

9

5

a)

b)

LS

2

RS

1

2

6

3

4

0

3

0

0

4

5

0

5

0

7

6

8

0

7

0

0

8

9

0

9

0

Rys.2.16 Reprezentowanie drzewa binarnego za pomoc

ą tablic.

W

proponowanym tutaj sposobie reprezentowania drzewa binarnego

wykorzystuje si

Ċ dwie tablice jednowymiarowe LS i RS. Dla pewnego indeksu

i elementy tablic LS[i] i RS[i] s

áuĪą do pamiĊtania indeksów odpowiednio

lewego i prawego syna w

Ċzáa i.

Ze wzgl

Ċdów praktycznych związanych z zastosowaniem drzew binarnych

w algorytmach istotny jest sposób (kolejno

Ğü) przechodzenia wĊzáów takiego

drzewa. Drzewo pokazane na rys.2.17, które pos

áuĪy jako przykáadowe podczas

prezentowania ró

Īnych metod przechodzenia drzewa binarnego.

1

2

5

4

3

6

8

7

Rys.2.17 Przyk

áad drzewa binarnego.

Zdefiniowane zostan

ą trzy metody przechodzenia (odwiedzania) wĊzáów

drzewa binarnego.

Przechodzenie drzewa metod

ą preorder

Odwiedzanie kolejnych w

Ċzáów drzewa binarnego metodą preorder odbywa siĊ

wed

áug algorytmu:

1. Odwied

Ĩ pewien wĊzeá.

2. Przejd

Ĩ metodą preorder kolejno poddrzewa: lewe i prawe, których

korzeniami s

ą synowie rozwaĪanego wĊzáa.

- 51 -

Ogólny schemat metody preorder przedstawiono na rys.2.18a, a kolejno

Ğü

przechodzenia w

Ċzáów drzewa binarnego z rys.2.17 zaznaczono na rys.2.18b.

Przechodzenie rozpocz

Ċto od korzenia.

1

2

3

a)

1

2

5

4

3

6

8

7

1

8

6

7

2

5

4

3

b)

Rys.2.18 Ilustracja metody preorder.

Do okre

Ğlenia metody preorder uĪyto samego definiowanego pojĊcia (metoda

preorder). Taki sposób definiowania nazywa si

Ċ rekurencyjnym i bĊdzie

zastosowany tak

Īe przy definiowaniu dwóch pozostaáych metod.

Przechodzenie drzewa metod

ą postorder

Odwiedzanie kolejnych w

Ċzáów drzewa binarnego metodą postorder odbywa

si

Ċ wedáug algorytmu:

1. Przejd

Ĩ metodą postorder kolejne poddrzewa: lewe i prawe, których

korzeniami s

ą synowie rozwaĪanego wĊzáa.

2. Odwied

Ĩ rozwaĪany wĊzeá.

Ogólny schemat metody postorder przedstawiono na rys.2.19a, a kolejno

Ğü

przechodzenia w

Ċzáów drzewa binarnego z rys.2.17 zaznaczono na rys.2.19b.

3

1

2

a)

1

2

5

4

3

6

8

7

8

5

7

6

4

3

1

2

b)

Rys.2.19 Ilustracja metody postorder.

Przechodzenie drzewa metod

ą inorder

Odwiedzanie kolejnych w

Ċzáów drzewa binarnego metodą inorder odbywa siĊ

wed

áug algorytmu:

- 52 -

background image

1. Przejd

Ĩ metodą inorder lewe poddrzewo potomków rozwaĪanego wĊzáa.

2. Odwied

Ĩ rozwaĪany wĊzeá.

3. Przejd

Ĩ metodą inorder prawe poddrzewo potomków rozwaĪanego wĊzáa.

Ogólny schemat metody inorder przedstawiono na rys.2.20a, a kolejno

Ğü

przechodzenia w

Ċzáów drzewa binarnego z rys.2.17 zaznaczono na rys.2.20b.

2

1

3

a)

1

2

5

4

3

6

8

7

5

7

8

6

3

4

2

1

b)

Rys.2.20 Ilustracja metody inorder.

Drzewa regularne i pe

áne

Zdefiniujemy jeszcze dwie podklasy drzew binarnych tj. drzewa regularne i
drzewa pe

áne.

Definicja 2.17

Regularnym drzewem binarnym nazywamy drzewo, w którym ka

Īdy z wĊzáów

jest albo li

Ğciem, albo posiada jednoczeĞnie lewego i prawego syna.

a)

b)

Rys.2.21 Drzewa binarne: regularne (a) i nieregularne (b).

Zgodnie z definicj

ą 2.17 drzewo na rys.2.21a jest regularne, podczas gdy

drzewo na rys.2.21b nie jest.

Definicja 2.18

Drzewo binarne nazywamy pe

ánym gdy istnieje liczba k taka, Īe dla kaĪdego

w

Ċzáa o gáĊbokoĞci mniejszej niĪ k wystĊpują oba wĊzáy bĊdące jego synami, a

ka

Īdy wĊzeá o gáĊbokoĞci k jest liĞciem.

- 53 -

a)

b)

Rys.2.22 Drzewa binarne: pe

áne (a) i niepeáne (b).

Zatem pe

áne drzewo binarne to takie drzewo, w którym dla wszystkich wĊzáów

wewn

Ċtrznych (tj. nie bĊdących liĞümi) wystĊpują jednoczeĞnie obaj synowie, a

g

áĊbokoĞü wszystkich liĞci jest jednakowa. Zgodnie z definicją 2.18 drzewo na

rys.2.22a jest pe

áne, podczas gdy drzewo na rys.2.22b nie jest.

2.6.3 U

Īycie struktur wskaĨnikowych

Podobnie jak listy, drzewa cz

Ċsto są reprezentowane przy uĪyciu struktur ze

wska

Ĩnikami. Analogicznie do elementów listy, wĊzáy drzewa są wtedy

strukturami o kilku polach, wsród których wyst

Ċpuje pole klucza oraz

dodatkowe pola przeznaczone do pami

Ċtania wskaĨników do innych wĊzáów

(rys.2.23). Liczba i sposób interpretacji tych wska

Ĩników na ogóá zaleĪy od

rodzaju drzewa.

key

...

Rys.2.23 W

Ċzeá drzewa reprezentowanego za pomocą struktur ze wskaĨnikami.

Drzewa binarne

Struktura pojedynczego w

Ċzáa drzewa binarnego jest pokazana na rys.2.24.

key

p

left right

Rys.2.24 W

Ċzeá drzewa binarnego jako struktura ze wskaĨnikami.

W ka

Īdym wĊĨle drzewa binarnego jest pamiĊtana czĊĞü informacyjna wĊzáa

(pole key) oraz wska

Ĩniki p - do wĊzáa rodzica, left – do lewego syna i right

do prawego syna tego w

Ċzáa. W pseudokodzie dla pewnego wĊzáa x operowaü

- 54 -

background image

b

Ċdziemy odpowiednio atrybutami key[x], p[x], left[x] oraz right[x]. JeĞli

p[x]=nil, to w

Ċzeá x jest korzeniem. JeĞli natomiast left[x]=nil lub right[x]=nil to

w

Ċzeá x nie ma odpowiednio lewego lub prawego syna. Atrybut root[T] drzewa

T oznacza wska

Ĩnik na korzeĔ drzewa. JeĞli root[T]=nil to drzewo jest puste.

Przyk

áad reprezentowania drzewa binarnego z rys.2.25a przy uĪyciu

wska

Ĩników pokazano na rys.2.25b.

a)

1

3

2

5

4

6

1

nil

3

2

4

5

6

root[ ]

T

b)

nil

nil

nil

nil

nil

nil

nil

Rys.2.25 Proste drzewo binarne jako struktura ze wska

Ĩnikami.

Drzewa o dowolnej strukturze

W przypadku je

Ğli na strukturĊ drzewa nie nakáada siĊ wstĊpnych ograniczeĔ,

tzn. liczba synów ka

Īdego wĊzáa nie jest z góry ustalona, bardziej odpowiednia

dla pojedynczego w

Ċzáa jest struktura pokazana na rys.2.26. UmoĪliwia ona

reprezentacj

Ċ dowolnego drzewa o n wĊzáach w pamiĊci

n

O

.

key

p

leftchild rightsibling

Rys.2.26 W

Ċzeá drzewa dowolnego jako struktura ze wskaĨnikami.

W ka

Īdym wĊĨle drzewa wystĊpują teraz nastĊpujące pola:

p[x]

- wska

Ĩnik na wĊzeá-rodzic,

key[x] -

zawarto

Ğü informacyjna wĊzáa,

leftchild[x]

- wska

Īnik na wĊzeá-syn poáoĪony najbardziej z lewej,

rightsibling[x] - wska

Īnik na prawego „brata” tj. prawy sąsiedni wĊzeá

b

Ċdący synem tego samego wĊzáa-rodzica.

- 55 -

W pseudokodzie dla pewnego w

Ċzáa x operowaü bĊdziemy odpowiednio

atrybutami p[x], key[x], leftchild[x] oraz rightsibling[x]. Je

Ğli wĊzeá x nie ma

synów, to leftchild[x]=nil. Je

Ğli natomiast jest on najbardziej na prawo

po

áoĪonym synem pewnego wĊzáa to rightsibling[x]=nil. Przykáad

reprezentowania drzewa z rys.2.27 przy u

Īyciu wskaĨników pokazano na

rys.2.28.

A

D

B

F

E

C

I

G

H

J

L

M

N

K

Rys.2.27 Drzewo o strukturze dowolnej.

C

B

K

E

F

D

nil

nil

nil

nil

A

nil

root[ ]

T

nil

nil

I

J

nil

G

H

nil

nil

M

N

nil

nil

nil

L

nil

nil

nil

Rys.2.28 Drzewo z rys.2.27 jako struktura ze wska

Ĩnikami.

2.7 Rekursja

Rekursj

Ċ nazywaną takĪe rekurencją zastosowaliĞmy juĪ, definiując metody

przechodzenia w

Ċzáów drzewa binarnego.

- 56 -

background image

Zastosowanie rekurencji cz

Ċsto prowadzi do bardziej przejrzystych i

zrozumia

áych definicji i algorytmów. Przykáadami są m.in. takĪe rekurencyjne

definicje listy i drzewa binarnego.

Definicja 2.19 (Rekurencyjna definicja listy)

List

ą nazywamy strukturĊ zdefiniowaną na skoĔczonym zbiorze elementów,

która:
x albo nie zawiera Īadnych elementów i jest nazywana listą pustą,
x albo jest konkatenacją (poáączeniem) elementu i listy.

Definicja 2.20 (Rekurencyjna definicja drzewa binarnego)

Drzewo binarne jest struktur

ą zdefiniowaną na skoĔczonym zbiorze wĊzáów w

ten sposób,

Īe:

x albo nie zawiera Īadnych wĊzáów i jest nazywane drzewem pustym,
x albo skáada siĊ z trzech rozáącznych zbiorów wĊzáów: korzenia, drzewa

binarnego nazywanego lewym poddrzewem oraz drzewa binarnego
nazywanego prawym poddrzewem.

Rekurencj

Ċ stosuje siĊ powszechnie takĪe jako metodĊ organizacji obliczeĔ.

Definicja 2.21

Procedur

Ċ, która bezpoĞrednio lub poĞrednio wywoáuje samą siebie nazywamy

rekurencyjn

ą.

Przyk

áady algorytmów rekurencyjnych

Przyk

áad 2.1

Typowym zadaniem, gdzie mo

Īna zastosowaü rekurencjĊ jest obliczanie potĊgi

dodatniej liczby m wed

áug zaleĪnoĞci:

¯

®

­

t

u



0

dla

1

dla

1

1

n

n

m

m

m

n

n

.

(2.1)

Zak

áadamy, Īe wykáadnik potĊgi n przyjmuje wartoĞci caákowite nieujemne. Jak

wynika z zale

ĪnoĞci (2.1) w celu obliczenia n-tej potĊgi liczby m naleĪy

obliczy

ü (n-1)-szą potĊgĊ m i pomnoĪyü otrzymaną wartoĞü przez m.

- 57 -

Przypadkiem szczególnym jest n=0, kiedy warto

Ğü potĊgi wynosi 1. Algorytm

taki realizuje procedura rekurencyjna K.2.12.

K.2.12

POT

ĉGA-M-DO-N(m,n)

1

je

Ğli n=0

2

to zwró

ü 1

3

inaczej zwró

ü (m * POT

ĉGA-M-DO-N(m,n-1))

W kolejnym wywo

áaniu procedura POTĉGA-M-DO-N sprawdza wartoĞü

wyk

áadnika potĊgi n. JeĞli wartoĞü ta wynosi 0, wówczas jako wynikiem tego

wywo

áania procedury jest wartoĞü 1. W przeciwnym razie procedura wywoáuje

sam

ą siebie w celu obliczenia

m

, obliczona warto

Ğü jest mnoĪona przez m,

po czym obliczony iloczyn jest zwracany jako efekt bie

Īącego wywoáania

procedury.

1



n

Dzia

áanie procedury rekurencyjnej áatwiej jest Ğledziü przy pomocy prostej

symulacji graficznej, przedstawiaj

ącej kolejne wywoáania oraz zwracane

warto

Ğci [8]. Na rys.2.29 pokazano w ten sposób porządek wywoáaĔ

rekrencyjnych oraz zwracane warto

Ğci podczas obliczania wartoĞci

3

.

4

Wywoáanie: 1

Warto

Ğü: 81

m: 3
n: 4

Wywoáanie: 2

Warto

Ğü: 27

m: 3
n: 3

Wywoáanie: 3

Warto

Ğü: 9

m: 3
n: 2

Wywoáanie: 4

Warto

Ğü: 3

m: 3
n: 1

Wywoáanie: 5

Warto

Ğü: 1

m: 3
n: 0

Rys.2.29 Ilustracja wywo

áaĔ w procedurze rekurencyjnej obliczania potegi.

Pierwsze wywo

áanie procedury ma postaü, POTĉGA-M-DO-N(3,4), zatem

najbardziej po

áoĪony na lewo prostokąt pokazuje wartoĞci parametrów m i n

jako równe odpowiednio 3 i 4. W kolejnych wywo

áaniach wartoĞü n zmniejsza

si

Ċ kaĪdorazowo o 1, aĪ do osiągniĊcia wartoĞci 0, co koĔczy dalsze wywoáania.

Wówczas s

ą obliczane wartoĞci kolejnych potĊg i zwracane na coraz wyĪsze

poziomy wywo

áaĔ, przy czym na najwyĪszy poziom jest zwracany wynik

ko

Ĕcowy wynoszący 81.

Przyk

áad 2.2

Jako drugi przyk

áad rozwaĪymy przedstawiony w [1] algorytm przechodzenia

metod

ą inorder drzewa binarnego reprezentowanego za pomocą tablic LS i RS

(zob.rys.2.16). Procedura przechodzenia jest przedstawiona jako kod K.2.13.

- 58 -

background image

K.2.13

DRZB-INORDER(w

Ċzeá)

1

je

Ğli LS[w

Ċzeá]z0

2

to

DRZB-INORDER(LS[w

Ċzeá])

3

NUMER[w

Ċzeá]

m

licznik

4

licznik

m

licznik+1

5

je

Ğli RS[w

Ċzeá]z0

6

to

DRZB-INORDER(RS[w

Ċzeá])

W algorytmie przyj

Ċto, Īe istnieje pewna zmienna globalna licznik, na początku

równa 1. Przy pierwszym wywo

áaniu procedury parametr wejĞciowy wĊzeá

powinien mie

ü takĪe wartoĞü 1. Wynikiem koĔcowym jest wypeánienie tablicy

NUMER okre

Ğlającej kolejnoĞü przechodzenia wĊzáów drzewa w ten sposób, Īe

element NUMER[i] zawiera liczb

Ċ naturalną pokazującą jako który z kolei jest

odwiedzany w

Ċzeá i.

Pytania kontrolne

1. Omówi

ü listĊ dwukierunkową i jej reprezentacjĊ przy uĪyciu wskaĨników.

2. Przedstawi

ü podstawowe operacje na listach:

a) przeszukiwanie listy;
b) w

áączanie nowego elementu;

c) usuwanie z listy;
d) odwracanie kolejno

Ğci elementów.

3.

Omówi

ü stos i jego reprezentacjĊ tablicową. Przedstawiü podstawowe

operacje na stosie.

4.

Omówi

ü kolejkĊ i jej reprezentacjĊ tablicową. Przedstawiü podstawowe

operacje dla kolejki.

5.

Przedstawi

ü algorytm przejĞcia od zapisu infiksowego na zapis

postfiksowy dla prostych wyra

ĪeĔ.

6. Omówi

ü sposoby przedstawienia listy za pomocą:

a) kilku tablic;

- 59 -

b) jednej tablicy.

7. Poda

ü definicjĊ i sposoby reprezentacji grafów.

8. Poda

ü definicjĊ i sposoby reprezentacji drzew.

9. Poda

ü rekurencyjną definicjĊ listy i drzewa.

Zadania

1. Zaproponowa

ü sposób przedstawienia stosu za pomocą listy. Napisaü

procedury POP i PUSH dla reprezentacji listowej.

2. Zaproponowa

ü sposób przedstawienia kolejki za pomocą listy. Napisaü

procedury ENQUEUE i DEQUEUE dla reprezentacji listowej.

3. Napisa

ü w pseudokodzie algorytm wyznaczania wartoĞci prostych wyraĪeĔ

zapisanych w notacji postfiksowej. Zak

áada siĊ, Īe wyraĪenia zawierają

tylko pojedyncze cyfry oraz znaki operacji + i *. Nale

Īy wykorzystaü stos.

4. Napisa

ü algorytm zliczania elementów w podanej liĞcie:

a) bez wykorzystania rekursji;
b) z wykorzystaniem rekursji.

5. Rozwa

Īyü listy zagnieĪdĪone, tj. takie, których elementy mogą same byü

listami. Stosuj

ąc rekursjĊ napisaü algorytm wyznaczający ogólną liczbĊ

elementów w listach o dowolnym stopniu zagnie

ĪdĪenia.

6.

Wie

Īe Hanoi. Stosując rekursjĊ naleĪy zaprogramowaü przeniesienie n

dysków z pr

Ċta A na prĊt B, wykorzystując przy tym prĊt C jako

pomocniczy. Funkcja powinna zwraca

ü iloĞü ruchów potrzebnych do

wykonania takiej operacji. Wej

Ğciem jest liczba dysków n.

Powinny przy tym by

ü speánione nastĊpujące warunki:

- tylko jeden dysk moĪe byü przenoszony równoczeĞnie,
- wszystkie dyski mają róĪne Ğrednice i nigdy dysk wiĊkszy nie moĪe byü

po

áoĪony na mniejszym,

- wyjĞciowym poáoĪeniem jest sytuacja na rysunku.

- 60 -

background image

3

Zastosowanie drzew i algorytmy przeszukiwania

3.1 Drzewa przeszukiwa

Ĕ binarnych

Drzewa przeszukiwa

Ĕ binarnych okreĞlane takĪe jako drzewa BST (binary

search trees) stanowi

ą specjalną klasĊ drzew binarnych, dla których moĪna

stosunkowo

áatwo skonstruowaü podstawowe algorytmy jak: wyszukiwanie,

minimum, maksimum, do

áączanie itd. Podstawowe operacje na drzewach BST

wymagaj

ą czasu proporcjonalnego do wysokoĞci drzewa.

Definicja 3.1

Drzewem przeszukiwa

Ĕ binarnych (BST) nazywamy drzewo binarne, w którym

warto

Ğci kluczy są przechowywane w taki sposób, aby speániaáy tzw. wáasnoĞü

drzewa BST, zgodnie z któr

ą dla dowolnego wĊzáa x zachodzi:

x jeĞli y jest wĊzáem lewego poddrzewa wĊzáa x, to

> @

>

x

key

y

key

@

d

oraz

x jeĞli y jest wĊzáem prawego poddrzewa wĊzáa x, to

> @

>

x

key

y

key

t

@

.

Przyk

áady drzew BST przedstawia rys. 3.1.

a)

5

3

5

2

7

8

b)

2

5

8

5

3

7

Rys.3.1 Przyk

áady drzew BST.

W drzewach BST z rys.3.1a i 3.1b wyst

Ċpują dokáadnie te same wartoĞci

kluczy, lecz ze wzgl

Ċdu na wiĊkszą wysokoĞü drzewo z rys.3.1b jest mniej

efektywne podczas wykonywania typowych operacji.

- 61 -

Podana w

áasnoĞü drzewa BST pozwala w prosty sposób posortowaü rosnąco

(wypisa

ü w porządku rosnącym) klucze wszystkich wĊzáów drzewa. W tym

celu wystarczy wykorzysta

ü metodĊ przechodzenia inorder, jak uczyniono to w

algorytmie przedstawionym jako kod K.3.1.

K.3.1

DRZB-INORDER1(x)
1

je

Ğli x

z

nil

2

to

{ DRZB-INORDER1(left[x])

3

wypisz key[x]

4

DRZB-INORDER1(right[x]) }

W algorytmie za

áoĪono, Īe drzewo BST jest reprezentowane za pomocą

struktury ze wska

Ĩnikami. Parametrem procedury przy pierwszym jej

wywo

áaniu jest wskaĨnik na wĊzeá-korzeĔ. Procedura sprawdza, czy rozwaĪany

w

Ċzeá istnieje (linia 1), po czym realizuje kolejno nastĊpujące czynnoĞci:

wywo

áuje przechodzenie lewego poddrzewa, wypisuje wartoĞü klucza w wĊĨle

oraz wywo

áuje przechodzenie prawego poddrzewa. W ten sposób dla drzewa z

rys.3.1 zostanie wypisany ci

ąg kluczy: 2 3 5 5 7 8.

3.1.1

Przeszukiwanie w drzewach BST

Przeszukiwanie w drzewie BST jest realizowane przy pomocy rekursywnej
funkcji BST-POSZ(x,k) (kod K.3.2).

K.3.2

BST-POSZ(x,k)
1

je

Ğli x=nil lub k= key[x]

2

to zwró

ü x

3

je

Ğli k<key[x]

4

to zwró

ü BST-POSZ(left[x],k)

5

inaczej zwró

ü BST-POSZ(right[x],k)

Parametr x jest wska

Ĩnikiem do pewnego wĊzáa (w szczególnoĞci moĪe byü

wska

Ĩnikiem do korzenia drzewa), a k wartoĞcią poszukiwanego klucza.

Przeszukiwanie odbywa si

Ċ w poddrzewie, którego korzeniem jest x. Funkcja

zwraca wska

Ĩnik do znalezionego wĊzáa lub nil jeĞli wĊzeá o podanym kluczu

nie istnieje. Przeszukiwanie rozpoczyna si

Ċ od wĊzáa początkowego i jest

kontynuowane w dó

á drzewa. Dla kaĪdego wĊzáa x, który nie jest pusty,

- 62 -

background image

algorytm porównuje warto

Ğü klucza dla tego wĊzáa z wartoĞcią poszukiwaną k.

Je

Ğli wartoĞci te są równe, to przeszukiwanie zostaje przerwane (wĊzeá zostaá

znaleziony). Je

Ğli x ma wartoĞü nil to przeszukiwanie takĪe zostaje przerwane

(w

Ċzeá nie zostaá znaleziony). JeĞli natomiast sprawdzany wĊzeá ma wartoĞü

klucza inn

ą od poszukiwanej, wówczas korzystamy z wáasnoĞci drzewa BST w

nast

Ċpujący sposób:

x poszukujemy dalej tylko w lewym poddrzewie, jeĞli wartoĞü

poszukiwanego klucza by

áa mniejsza od napotkanego,

x poszukujemy dalej tylko w prawym poddrzewie, jeĞli wartoĞü

poszukiwanego klucza by

áa niemniejsza od napotkanego.

Algorytm przeszukiwania w drzewie BST mo

Īna takĪe napisaü nie stosując

rekursji. Wersj

Ċ bez rekursji okreĞlaną takĪe jako wersja iteracyjna przedstawia

kod K.3.3.

K.3.3

BST-POSZ-ITER(x,k)
1

dopóki

x

znil i kzkey[x]

2

wykonuj je

Ğli k<key[x]

3

to

x

mleft[x]

4

inaczej

x

mright[x]

5

zwró

ü x

3.1.2

Inne operacje na drzewach BST

Poszukiwanie w

Ċzáa o minimalnym kluczu

Algorytm poszukiwania w

Ċzáa o minimalnym kluczu w drzewie BST realizuje

funkcja BST-MIN(x) (kod K.3.4).

K.3.4

BST-MIN(x)
1

dopóki

left[x]

znil

2

wykonuj

x

mleft[x]

3

zwró

ü x

Przeszukiwanie rozpoczyna si

Ċ od dowolnego wĊzáa x i odbywa siĊ w

poddrzewie, którego korzeniem jest w

Ċzeá x. WĊzeá o minimalnym kluczu jest

poszukiwany wed

áug prostej strategii „podąĪania” za wskaĨnikiem left

- 63 -

kolejnych w

Ċzáów, aĪ do napotkania wĊzáa, dla którego wskaĨnik left[x] jest

pusty. W

Ċzeá o minimalnym kluczu jest zatem lewym skrajnym wĊzáem w

przeszukiwanym poddrzewie.

W analogiczny sposób mo

Īna napisaü funkcjĊ wyszukiwania wĊzáa o

maksymalnym kluczu.

àatwo zauwaĪyü, Īe obie funkcje dziaáają w czasie O(h),

gdzie h jest wysoko

Ğcią drzewa BST.

Nast

Ċpniki i poprzedniki

Problem poszukiwania nast

Ċpnika pewnego wĊzáa x w drzewie BST polega na

udzieleniu odpowiedzi na pytanie: który w

Ċzeá bĊdzie odwiedzany jako

nast

Ċpny po x podczas przechodzenia drzewa w porządku inorder. JeĞli

wszystkie klucze s

ą róĪne, to nastĊpnikiem wĊzáa x jest wĊzeá o najmniejszym

kluczu, wi

Ċkszym niĪ key[x]. Drzewo BST zapewnia wyznaczenie nastĊpnika

bez wykonywania operacji porównania. Skonstruujemy funkcj

Ċ BST-NAST(x)

(kod K.3.5), gdzie parametr x jest wska

Ĩnikiem na rozwaĪany wĊzeá, a w

wyniku jest zwracany wska

Ĩnik na nastĊpnik wĊzáa x. JeĞli x nie posiada

nast

Ċpnika, wówczas jest zwracany wskaĨnik pusty nil.

K.3.5

BST-NAST(x)
1

je

Ğli right[x]

znil

2

to zwró

ü DRZB-MIN(right[x])

3

y

mp[x]

4

dopóki

x

znil i x=right[y]

5

wykonuj

{ x

my

6

y

mp[y] }

7

zwró

ü y

W algorytmie K.3.5 rozwa

Īono dwa przypadki. JeĞli wĊzeá x posiada prawe

poddrzewo, to nast

Ċpnik wyznacza siĊ áatwo, gdyĪ jest to najmniejszy wĊzeá

prawego poddrzewa. W przypadku, gdy w

Ċzeá x nie ma prawego poddrzewa

(ale ma nast

Ċpnik y), to y jest najniĪszym przodkiem wĊzáa x, takim, Īe jego

lewy syn jest tak

Īe przodkiem x.

W drzewie BST na rys.3.2 nast

Ċpnikiem wĊzáa 13 jest wĊzeá 15. Aby go

wyznaczy

ü, wystarczy przejĞü w górĊ drzewa do napotkania wĊzáa, który jest

lewym w

Ċzáem-synem swojego rodzica. Przeszukiwanie takiego wĊzáa odbywa

- 64 -

background image

si

Ċ w wierszach 3-6 algorytmu K.3.5. Znaleziona wartoĞü y jest zwracana w

wierszu 7.

15

5

7

3

18

20

17

4

2

13

9

Rys.3.2 Drzewo BST, w którym nast

Ċpnikiem wĊzáa 13 jest wĊzeá 15.

Dla drzewa o wysoko

Ğci h algorytm wyznaczania nastĊpnika, podobnie jak

analogiczny algorytm wyznaczania poprzednika, dzia

áają w czasie O(h).

Operacje wstawiania i usuwania

Operacje wstawiania i usuwania w drzewie BST tym ró

Īnią siĊ od dotychczas

omówionych operacji,

Īe modyfikują (zmieniają) one dynamiczną strukturĊ

drzewa. W ogólnym przypadku dynamiczna struktura drzewa musi by

ü wtedy

przeorganizowana tak, aby zachowa

ü wáasnoĞü drzewa BST. Omówimy

procedur

Ċ wstawiania nowego wĊzáa z do drzewa przeszukiwaĔ binarnych T

(kod K.3.6).

K.3.6

BST-WSTAW(T,z)
1

y

mnil

2

x

mroot[T]

3

dopóki

x

znil

4

wykonuj

{ y

mx

5

je

Ğli key[z]<key[x]

6

to

x

mleft[x]

7

inaczej

x

mright[x] }

8

p[z]

my

9

je

Ğli y=nil

10

to

root[T]

mz

11

inaczej je

Ğli key[z]<key[y]

12

to

left[y]

mz

13

inaczej

right[y]

mz

- 65 -

Zak

áada siĊ, Īe wstawiany wĊzeá przygotowano w ten sposób Īe key[z]=v,

left[z]=nil oraz right[z]=nil. W wyniku wykonania procedury wstawiania,
drzewo wej

Ğciowe T oraz pole p[z] są modyfikowane tak, Īe z staje siĊ wĊzáem

drzewa T.

Podobnie jak w przypadku procedury wyszukiwania, przegl

ądanie, drzewa

rozpoczyna si

Ċ w korzeniu i przebiega w dóá drzewa. WskaĨnik x postĊpuje po

pewnej

ĞcieĪce w drzewie, a zmienna y zawiera wskazanie na rodzica wĊzáa x.

W wierszach od 3 do 7 wska

Ĩniki x i y są przesuwane w dóá drzewa w kierunku

prawym lub lewym, w zale

ĪnoĞci od wyniku porównania kluczy elementów

wstawianego i napotkanego. Proces ten trwa a

Ī do chwili, gdy x przyjmie

warto

Ğü nil i w tym wáaĞnie miejscu jest wstawiany nowy wĊzeá. Wstawianie

odbywa si

Ċ w wierszach od 8 do 13.

3.2 Kopce

3.2.1

Definicja i w

áasnoĞü kopca

Definicja 3.2

Kopiec (heap) to struktura, która mo

Īe byü rozpatrywana jako rodzaj „prawie

pe

ánego” drzewa binarnego (rys.3.3a). Drzewo to jest peáne w tym sensie, Īe

jest wype

ánione na wszystkich poziomach z wyjątkiem byü moĪe najniĪszego,

który jest wype

ániony od lewej do prawej do pewnego miejsca. JednoczeĞnie

rozwa

Īa siĊ tablicĊ A, której elementy odpowiadają wĊzáom drzewa w sposób

wynikaj

ący z porównania rysunków 3.3a i 3.3b.

Tablica A reprezentuj

ąca kopiec posiada dwa nastĊpujące atrybuty:

length[A]

- liczba elementów w A,

heap-size[A]

- liczba elementów kopca,

dla których zachodzi nierówno

Ğü:

heap-size[A]

d length[A].

- 66 -

background image

a)

16

14

7

8

10

9

3

1

7

3

6

2

5

4

4

2

9

8

1

10

b)

A

3

1

2

3

4

5

6

7

8

9

10

11

2

4

1

14

16

10

8

7

9

Rys.3.3 Reprezentowanie kopca przy pomocy drzewa binarnego i tablicy.

Zak

áada siĊ, Īe korzeniem drzewa jest A[1], a wszystkie elementy z indeksem

wi

Ċkszym od heap-size[A] nie zawierają elementów kopca. Przy takim sposobie

reprezentowania kopca, mo

Īna na podstawie danego indeksu i pewnego wĊzáa

obliczy

ü indeks jego rodzica, a takĪe indeksy lewego i prawego syna. Realizują

to proste funkcje PARENT(i) (kod.3.7), LEFT(i) (kod.3.8) oraz RIGHT(i)
(kod.3.9).

K.3.7

K.3.8

K.3.9

PARENT(i)
1

zwró

ü

¬i/2¼

LEFT(i)
1 zwró

ü 2i

RIGHT(i)
1

zwró

ü 2i+1

W

áasnoĞü kopca

Kopiec posiada specjaln

ą wáasnoĞü, która mówi, Īe dla kaĪdego wĊzáa i, który

nie jest korzeniem zachodzi

A[PARENT(i)]

t A[i].

Z w

áasnoĞci kopca wynika, Īe najwiĊkszy element kopca znajduje siĊ w

korzeniu, a poddrzewa ka

Īdego wĊzáa zawierają wartoĞci mniejsze niĪ wartoĞü

umieszczona w tym w

ĊĨle. PoniewaĪ kopiec jest budowany jako peáne drzewo

binarne, st

ąd jego wysokoĞü dla n wĊzáów wynosi 4(lgn). Jest to takĪe istotna

cecha kopca, z której wynika,

Īe podstawowe algorytmy na kopcach dziaáają w

czasie O(lgn).

- 67 -

3.2.2

Algorytmy na kopcach

Przywracanie w

áasnoĞci kopca

Dzia

áania na kopcu mogą prowadziü do zaburzenia jego wáasnoĞci, stąd

podstawow

ą operacją jest procedura przywracania wáasnoĞci kopca. W

algorytmie K.3.10 za

áoĪono, Īe kopiec jest reprezentowany przy pomocy

tablicy A, dla której w w

ĊĨle A[i] naleĪy przywróciü wáasnoĞü kopca.

K.3.10

KOPIEC-PRZYWR(A,i)
1

l

m LEFT(i)

2

r

m RIGHT(i)

3

je

Ğli l

dheap-size[A] i A[l]>A[i]

4

to

najwi

Ċkszyml

5

inaczej

najwi

Ċkszymi

6

je

Ğli r

dheap-size[A] i A[r]>A[najwiĊkszy]

7

to

najwi

Ċkszymr

8

je

Ğli najwi

Ċkszyzi

9

to

{ zamie

Ĕ A[i]lA[najwiĊkszy]

10

KOPIEC-PRZYWR(A,najwi

Ċkszy)}

W ka

Īdym kroku procedury jest wybierany najwiĊkszy spoĞród elementów A[i],

A[LEFT(i)] i A[RIGHT(i)], a jego indeks zostaje zapami

Ċtany w zmiennej

najwi

Ċkszy. JeĞli najwiĊkszym okazaá siĊ A[i], to wáasnoĞü kopca w wĊĨle A[i]

jest spe

ániona i procedura koĔczy pracĊ. W przeciwnym razie, tj. gdy

najwi

Ċkszym okazaá siĊ jeden z synów wĊzáa A[i], nastĊpuje zamiana miejscami

w

Ċzáów A[i] oraz A[najwiĊkszy]. W wyniku wĊzeá A[i] oraz jego synowie

spe

ániają wáasnoĞü kopca. WĊzeá A[najwiĊkszy] ma teraz poprzednią wartoĞü

w

Ċzáa A[i], dlatego poddrzewo zaczepione w wĊĨle A[najwiĊkszy] moĪe nie

spe

ániaü juĪ wáasnoĞci kopca. W takim przypadku procedurĊ przywracania

nale

Īy wywoáaü rekurencyjnie dla poddrzewa z korzeniem A[najwiĊkszy].

Przyk

áadem zastosowania procedury K.3.10 jest przywrócenie wáasnoĞci kopca

strukturze z rys.3.4a. W wyniku otrzymujemy kopiec pokazany na rys.3.4b.

- 68 -

background image

a)

16

4

7

14

10

9

3

1

7

3

6

2

5

4

8

2

9

8

1

10

b)

16

14

7

8

10

9

3

1

7

3

6

2

5

4

4

2

9

8

1

10

Rys. 3.4 Efekt dzia

áania procedury przywracania wáasnoĞci kopca.

Jak wynika z rys.3.4a w

áasnoĞü kopca nie jest speániona dla wĊzáa o wartoĞci

klucza 4, tj. w

Ċzáa A[2], zatem pierwsze wywoáanie procedury przywracania

w

áasnoĞci kopca ma postaü KOPIEC-PRZYWR(A,2). Prowadzi ono do zamiany

miejscami w

Ċzáów A[2] i A[4], z kluczami odpowiednio 4 i 14. Taka zamiana

powoduje jednak zaburzenie w

áasnoĞci kopca w wĊĨle A[4], który ma teraz

warto

Ğü klucza 4, podczas gdy jego synami są wĊzáy A[8] i A[9], z kluczami

odpowiednio 2 i 8. Niezb

Ċdne jest zatem rekursywne wywoáanie KOPIEC-

PRZYWR(A,4), które prowadzi do zamiany miejscami w

Ċzáów A[4] i A[9], z

kluczami odpowiednio 4 i 8 oraz przywrócenia w

áasnoĞci kopca w caáym

poddrzewie, którego korzeniem jest w

Ċzeá A[2] (rys.3.4b).

Budowanie kopca

Za pomoc

ą procedury przywracania wáasnoĞci kopca moĪna z elementów

zadanej tablicy A[1..n] zbudowa

ü kopiec taki, Īe heap-size[A]=n. NaleĪy przy

tym zauwa

Īyü, Īe kaĪdy element podtablicy An/2¼+1..n] jest liĞciem w

drzewie binarnym reprezentuj

ącym kopiec. Elementy te zatem moĪna traktowaü

jako jednoelementowe kopce, w których w

áasnoĞü kopca na pewno jest

spe

ániona. Na przykáad dla tablicy wyjĞciowej A[1..10], pokazanej na rys. 3.5a

podtablic

ą liĞci jest A[6..10] (por.rys.3.5b).

Procedur

Ċ budowania kopca przedstawiono jako kod K.3.11.

K.3.11

KOPIEC-BUDUJ(A)
1

heap-size[A]

m length[A]

2

dla

i

m ¬length[A]/2¼ w_dóá_do 1

3

wykonuj

KOPIEC-PRZYWR(A,i)

- 69 -

a)

A

10

1

2

3

4

5

6

7

8

9

10

11

14 8

7

1

4

3

2

16

9

A [6..10]

b)

4

1

16

2

3

9

10

1

7

3

6

2

5

4

8

14

9

8

7

10

Rys.3.5 Zakres podtablicy li

Ğci (a) dla drzewa (b).

W algorytmie wykorzystano fakt,

Īe w wĊzáach podtablicy An/2¼+1..n]

w

áasnoĞü kopca jest juĪ speániona. NastĊpnie procedura przechodzi przez

pozosta

áe wĊzáy, tzn. wĊzáy podtablicy A[1..¬n/2¼] i wywoáuje w kaĪdym z nich

procedur

Ċ przywracania wáasnoĞci kopca. WĊzáy są przy tym odwiedzane

w kolejno

Ğci malejących numerów od ¬n/2¼ do 1. W kaĪdym z wĊzáów zostaje

wywo

áana procedura KOPIEC-PRZYWR, w efekcie czego poddrzewa

zaczepione w tych w

Ċzáach stają siĊ prawidáowymi kopcami.

Przyk

áadem uĪycia procedury KOPIEC-BUDUJ są pokazane na rys.3.7-3.11

kolejne kroki budowania kopca na podstawie tablicy z rys.3.5a. Drzewo
wyj

Ğciowe przedstawia rys.3.6.

4

1

16

2

3

9

10

1

7

3

6

2

5

4

8

14

9

8

7

10

Rys.3.6 Stan wyj

Ğciowy do budowania kopca z elementów tablicy z rys.3.5a.

- 70 -

background image

4

1

16

2

3

9

10

1

7

3

6

2

5

4

8

14

9

8

7

10

Rys.3.7 Stan po wywo

áaniu KOPIEC-PRZYWR(A,5).

4

1

16

14

3

9

10

1

7

3

6

2

5

4

8

2

9

8

7

10

Rys.3.8 Stan po wywo

áaniu KOPIEC-PRZYWR(A,4).

4

1

16

14

10

9

3

1

7

3

6

2

5

4

8

2

9

8

7

10

Rys.3.9 Stan po wywo

áaniu KOPIEC-PRZYWR(A,3).

4

16

7

14

10

9

3

1

7

3

6

2

5

4

8

2

9

8

1

10

Rys.3.10 Stan po wywo

áaniu KOPIEC-PRZYWR(A,2).

16

14

7

8

10

9

3

1

7

3

6

2

5

4

4

2

9

8

1

10

Rys.3.11 Stan po wywo

áaniu KOPIEC-PRZYWR(A,1).

- 71 -

3.2.3 Kolejki

priorytetowe

Kolejka priorytetowa to struktura przechowuj

ąca S elementów, z których kaĪdy

ma przyporz

ądkowaną wartoĞü klucza. Typowymi operacjami są wtedy:

wstawianie nowego, a tak

Īe wyszukiwanie oraz usuwanie elementu

o maksymalnym kluczu. Przyk

áadem zastosowania takiej kolejki jest

przydzielanie zasobów w komputerze pracuj

ącym wspóábieĪnie, tzn.

wykonuj

ącym wiĊcej niĪ jedno zadanie. Zadania do wykonania posiadają

priorytety i s

ą ustawiane w kolejce. Kiedy pewne zadanie koĔczy siĊ lub zostaje

przerwane, spo

Ğród oczekujących jest wybierane zadanie o najwyĪszym

priorytecie, co oznacza usuni

Ċcie go z kolejki. Okazuje siĊ, Īe kolejkĊ

priorytetow

ą oraz podstawowe operacje w takiej kolejce wygodnie jest

zrealizowa

ü przy pomocy kopca.

Usuwanie maksymalnego elementu

Usuwanie maksymalnego elementu z kolejki priorytetowej jest równoznaczne
z usuni

Ċciem maksymalnego elementu z kopca reprezentującego tĊ kolejkĊ.

Realizuje to algorytm K.3.12.

K.3.12

KOPIEC-USU

ē-MAX(A)

1

je

Ğli heap-size[A] < 1

2

to

b

áąd „kopiec pusty

3

max

m A[1]

4

A[1]

m A[heap-size[A]]

5

heap-size[A]

m heap-size[A]-1

6 KOPIEC-PRZYWR(A,1)
7

zwró

ü max

Linie 1 i 2 w funkcji K.3.12 zabezpieczaj

ą przed usuwaniem z pustej kolejki.

Elementem usuwanym jest zawsze korze

Ĕ kopca reprezentującego kolejkĊ

priorytetow

ą, tj. element A[1]. WartoĞü tego elementu jest zwracana w linii 7

jako wynik dzia

áania funkcji. Linie od 4 do 6 sáuĪą do zmodyfikowania kopca

(w tym przywrócenia w

áasnoĞci kopca) po usuniĊciu z niego maksymalnego

elementu.

Na rys.3.13-3.15 zilustrowano kolejne etapy usuwania maksymalnego elementu
z kolejki reprezentowanej przez kopiec z rys.3.12.

- 72 -

background image

16

14

7

8

10

9

3

1

7

3

6

2

5

4

4

2

9

8

1

10

Rys.3.12 Kopiec przed usuni

Ċciem maksymalnego elementu.

1

14

7

8

10

9

3

1

7

3

6

2

5

4

4

2

9

8

1

10

Rys.3.13 Kopiec po wykonaniu polecenia z linii 4 w procedurze K.3.12.

1

14

7

8

10

9

3

1

7

3

6

2

5

4

4

2

9

8

Rys.3.14 Kopiec po wykonaniu polecenia z linii 5 w procedurze K.3.12.

14

8

7

4

10

9

3

1

7

3

6

2

5

4

1

2

9

8

Rys.3.15 Kopiec po wywo

áaniu procedury KOPIEC-PRZYWR(A,1).

- 73 -

Dodawanie nowego elementu

Dodanie nowego elementu do kolejki priorytetowej polega na powi

Ċkszeniu

kopca o nowy w

Ċzeá tak, aby zostaá on wstawiony na wáaĞciwe miejsce.

Operacj

Ċ taką realizuje algorytm K.3.13.

K.3.13

KOPIEC-WSTAW(A,key)
1

heap-size[A]

m heap-size[A]+1

2

i

m heap-size[A]

3

dopóki

i > 1 i A[PARENT(i)] < key

4

wykonuj

{ A[i]

m A[PARENT(i)]

5

i

m PARENT(i) }

6

A[i]

m key

Parametrami procedury wstawiania s

ą: kopiec reprezentujący kolejkĊ

priorytetow

ą oraz klucz dodawanego elementu. Algorytm dziaáa w ten sposób,

Īe powiĊksza najpierw kopiec dodając nowy liĞü (linia 1). NastĊpnie w sposób
podobny jak procedura sortowania przez wstawianie, przechodzi

ĞcieĪkĊ od

nowego li

Ğcia do korzenia celem okreĞlenia wáaĞciwego miejsca dla

wstawianego elementu.

Na rys.3.17-3.20 zilustrowano kolejne etapy dodawania elementu z kluczem 15
do kolejki reprezentowanej przez kopiec z rys.3.16.

16

14

7

8

10

9

3

1

7

3

6

2

5

4

4

2

9

8

1

10

Rys.3.16 Kopiec przed dodaniem elementu z kluczem 15.

- 74 -

background image

16

14

7

8

10

9

3

1

7

3

6

2

5

4

4

2

9

8

1

10

11

Rys.3.17 Kopiec po wykonaniu polecenia z linii 1 w procedurze K.3.13.

16

14

7

8

10

9

3

1

7

3

6

2

5

4

4

2

9

8

1

10

11

7

Rys.3.18 Kopiec po 1-szym wykonaniu p

Ċtli w liniach 3y5 procedury K.3.13.

16

14

14

8

10

9

3

1

7

3

6

2

5

4

4

2

9

8

1

10

11

7

Rys.3.19 Kopiec po 2-gim wykonaniu p

Ċtli w liniach 3y5 procedury K.3.13.

16

15

14

8

10

9

3

1

7

3

6

2

5

4

4

2

9

8

1

10

11

7

Rys.3.20 Kopiec po wykonaniu polecenia z linii 6 w procedurze K.3.13.

Czas dzia

áania procedury KOPIEC-WSTAW(A,key) na n elementowym kopcu

wynosi O(lgn), poniewa

Ī jest równy dáugoĞci ĞcieĪki poprowadzonej od

nowego li

Ğcia do korzenia.

- 75 -

3.3 Przeszukiwanie w drzewach

3.3.1 Typy

zada

Ĕ przeszukiwania

Opracowanie

efektywnych procedur przeszukiwania jest kluczowym

zagadnieniem w dziedzinie algorytmów. Na rys.3.21 wyodr

Ċbniono dwie

podstawowe klasy problemów, które mog

ą byü rozwiązywane przy pomocy

przeszukiwania.

PRZESZUKIWANIE

Pozyskiwanie

informacji

z gotowych struktur

Generowanie

planów

rozwi

ązaĔ

Rys.3.21 Klasy zada

Ĕ przeszukiwania w drzewach.

Pierwsza grupa zada

Ĕ dotyczy przypadków, kiedy z istniejącej struktury naleĪy

uzyska

ü okreĞlone informacje, np. wyszukaü konkretny element w zadanym

drzewie binarnym. Inne przyk

áady moĪna podaü rozwaĪając drzewo na rys.3.22.

Henryk

Bogdan

Joanna

Franciszek

Zuzanna

Julia

Danuta

Józef

Jan

Rys.3.22 Drzewo zale

ĪnoĞci przodek-potomek.

Jest to struktura pokazuj

ąca zaleĪnoĞci przodek-potomek dla czáonków pewnej

rodziny. Przeszukiwanie w takim drzewie jest podstaw

ą do udzielania

odpowiedzi m.in. na nast

Ċpujące pytania:

x czy Zofia naleĪy do rodziny?
x czy Zuzanna jest potomkiem Bogdana?
itp.

- 76 -

background image

Druga grupa zada

Ĕ przeszukiwania dotyczy generowania planów rozwiązaĔ

i mo

Īe byü

zilustrowana przy pomocy prostej zabawki-uk

áadanki

przedstawionej na rys.3.23 [2].

Rys.3.23 Uk

áadanka.

8

1

2

6

7

5

3

4

1

2

3

5

4

8

6

7

stan pocz

ątkowy

stan docelowy

Uk

áadanka skáada siĊ z 8-miu segmentów, które mogą byü przemieszczane

w obr

Ċbie 9-ciu pól. Przyjmując za punkt wyjĞcia pewien stan początkowy,

nale

Īy tak przesuwaü segmenty, aby otrzymaü nowy ukáad przyjĊty jako stan

docelowy. Zadanie przeszukiwania w tym przypadku polega na automatycznym
wygenerowaniu takiego ci

ągu przesuniĊü segmentów, który prowadzi do stanu

docelowego. Powstaje w ten sposób drzewo przeszukiwa

Ĕ, którego wĊzáy

reprezentuj

ą bieĪące stany ukáadanki tj. chwilowe ukáady segmentów. Dla

pewnego w

Ċzáa w drzewie przeszukiwaĔ jego synami są stany osiągalne z tego

w

Ċzáa po wykonaniu pojedynczego przesuniĊcia (rys.3.24).

8

1

2

6

3

5

7

4

8

1

2

3

7

5

6

4

8

1

2

6

7

5

3

4

8

1

3

6

2

5

7

4

8

1

2

6

7

5

3

4

8

1

2

3

6

5

7

4

8

1

2

6

7

5

3

4

8

3

1

6

2

5

7

4

8

1

2

5

7

6

3

4

8

1

2

3

6

5

7

4

8

1

2

6

7

4

3

5

8

1

2

3

6

5

7

4

8

6

2

1

7

5

3

4

8

3

2

1

6

5

7

4

8

1

2

7

6

5

3

4

Rys.3.24 Drzewo stanów uk

áadanki.

Nale

Īy zwróciü uwagĊ na fakt, Īe w odróĪnieniu od zadaĔ pozyskiwania

informacji z gotowych struktur, w zadaniach generowania planów rozwi

ązaĔ

- 77 -

przeszukiwana struktura istnieje tylko konceptualnie, tzn. nie musi by

ü

wcze

Ğniej zbudowana w caáoĞci. Budowane są tylko jej niezbĊdne czĊĞci,

w miar

Ċ jak postĊpuje proces przeszukiwania.

Dla obu wymienionych klas zada

Ĕ przeszukiwania konieczne jest rozwiązanie

nast

Ċpujących problemów:

1. Dost

Ċp do wĊzáów

2. Systematyczne si

Ċganie do wĊzáów

3. Sprawdzanie

w

Ċzáów.

Dost

Ċp do wĊzáów

W przypadku przeszukiwania w gotowej strukturze dost

Ċp do wĊzáów jest

rozumiany jako mo

ĪliwoĞü odczytania wszystkich synów dowolnego wĊzáa.

Drzewa s

ą zazwyczaj reprezentowane tak, Īe operacja ta jest bardzo prosta (np.

wska

Ĩniki do synów wĊzáa x drzewa binarnego reprezentowanego za pomocą

struktury ze wska

Ĩnikami, odczytujemy za pomocą atrybutów left[x] i right[x], a

dla drzew dowolnych nale

Īy wykorzystaü atrybuty leftchild[x] oraz

rightsibling[x]).

W zadaniach generowania planów rozwi

ązaĔ dostĊp do wĊzáów polega na

otrzymaniu (wygenerowaniu) w

Ċzáów-synów dowolnego wĊzáa, przy czym

sposób otrzymania tych w

Ċzáów jest, ogólnie biorąc, zaleĪny od typu zadania.

W przypadku uk

áadanki konieczna jest procedura, która dla dowolnego ukáadu

segmentów generuje zbiór stanów „s

ąsiednich” otrzymywanych z bieĪącego

przez wykonanie pojedynczego przesuni

Ċcia.

Systematyczne si

Ċganie do wĊzáów

Problem dost

Ċpu do wĊzáów jest waĪnym, ale nie jedynym w zadaniach

przeszukiwania. Za

áóĪmy, Īe dla drzewa zaleĪnoĞci przodek-potomek (rys.3.22)

mamy odpowiedzie

ü na pytanie: czy wĊzeá Zuzanna wystĊpuje w tym drzewie?

Potrzebna jest wtedy okre

Ğlona strategia, wedáug której naleĪy siĊgaü do

kolejnych w

Ċzáów drzewa w trakcie przeszukiwania. Na ogóá stosuje siĊ dwie

podstawowe strategie przeszukiwania:
x strategia wszerz (BFS – Breadth First Search) oraz
x strategia w gáąb – (DFS - Depth First Search).

- 78 -

background image

Sprawdzanie w

Ċzáów

Operacja sprawdzania w

Ċzáów ma na celu ustalenie, czy wĊzeá osiągniĊty

w wyniku systematycznego si

Ċgania jest wĊzáem poszukiwanym.

3.3.2

Strategie wszerz i w g

áąb

Jak ju

Ī wspomniano systematyczne siĊganie do wĊzáów odbywa siĊ zwykle

wed

áug strategii wszerz lub wedáug strategii w gáąb. StrategiĊ siĊgania wszerz

pokazano schematycznie na rys.3.25. Zak

áada ona przeglądanie kolejno

wszystkich w

Ċzáów danego poziomu, a dopiero po ich wyczerpaniu przejĞcie do

nast

Ċpnego poziomu.

A

D

B

F

E

C

I

G

H

J

L

M

N

K

Rys.3.25 Przeszukiwanie wszerz.

Inaczej odbywa si

Ċ przeglądanie wĊzáów wedáug strategii w gáąb (rys.3.26).

W tym przypadku „odwiedzaj

ąc” wĊzáy naleĪy poruszaü siĊ maksymalnie w

á, a dopiero gdy przestaje to byü moĪliwe, powróciü do wĊzáa wyĪszego

poziomu.

A

D

B

F

E

C

I

G

H

J

L

M

N

K

Rys.3.26 Przeszukiwanie w g

áąb.

- 79 -

Inaczej odbywa si

Ċ przeglądanie wĊzáów wedáug strategii w gáąb (rys.3.26).

W tym przypadku „odwiedzaj

ąc” wĊzáy naleĪy poruszaü siĊ maksymalnie w

á, a dopiero gdy przestaje to byü moĪliwe, powróciü do wĊzáa wyĪszego

poziomu.

Postawimy teraz zadanie opracowania algorytmu przegl

ądającego wĊzáy

dowolnego drzewa wed

áug strategii wszerz. Zakáada siĊ przy tym, Īe drzewo

jest reprezentowane przy pomocy struktury ze wska

Ĩnikami. Algorytm

przegl

ądania realizuje funkcja DRZEWO-WSZERZ(W1,W2) (kod K.3.13).

Funkcja ta sprawdza, czy w

Ċzeá W2 jest wĊzáem potomnym wĊzáa W1, tzn. czy

W2 wyst

Ċpuje w poddrzewie, którego korzeniem jest W1.

K.3.13

DRZEWO-WSZERZ(W1, W2)
1 do_sprawdzenia

m nil

2

SYNOWIE(W1, do_sprawdzenia)

3 dopóki do_sprawdzenia

z nil

4

wykonuj

{ pierwszy

m PIERWSZY(do_sprawdzenia)

5 je

Ğli key[pierwszy] = key[W2] to zwróü W2

6 SYNOWIE(pierwszy, nowe_w

Ċzáy)

7 RESZTA(do_sprawdzenia)
8 NOWE-NA-KONIEC(do_sprawdzenia, nowe_w

Ċzáy) }

9 wypisz „w

Ċzáa nie znaleziono

W

algorytmie wykorzystano dwie struktury listowe: do_sprawdzenia

i nowe_w

Ċzáy, zawierające odpowiednio wĊzáy oczekujące aktualnie na

sprawdzenie oraz w

Ċzáy, które są synami bieĪącego wĊzáa. UĪyto takĪe

nast

Ċpujących pomocniczych procedur i funkcji:

SYNOWIE(w, lista_s)

dla w

Ċzáa w generuje listĊ lista_s

w

Ċzáów-synów tego wĊzáa,

PIERWSZY(lista_w)

dla niepustej listy w

Ċzáów lista_w

zwraca wska

Ĩnik na pierwszy wĊzeá,

RESZTA(lista_w)

w li

Ğcie wĊzáów lista_w usuwa

pierwszy w

Ċzeá,

NOWE-NA-KONIEC(lista_w1, lista_w2)

na koniec listy w

Ċzáów lista_w1

dodaje list

Ċ wĊzáów lista_w2.

Ich opracowanie pozostawia si

Ċ Czytelnikowi.

- 80 -

background image

Algorytm przeszukiwania w g

áąb moĪna otrzymaü dokonując niewielkiej

modyfikacji funkcji DRZEWO-WSZERZ. Podstawowa zmiana dotyczy linii 8,
gdzie wywo

áanie procedury NOWE-NA-KONIEC naleĪy zastąpiü wywoáaniem

analogicznej procedury NOWE-NA-POCZ

ĄTEK, która doáączy nowe wĊzáy,

b

Ċdące synami bieĪącego wĊzáa nie na koniec, lecz na początek listy

do_sprawdzenia.

3.3.3

Przeszukiwanie sterowane i niesterowane

Strategie wszerz i w g

áąb są przykáadami przeszukiwania niesterowanego w tym

sensie,

Īe porządek wedáug którego są sprawdzane wĊzáy drzewa jest z góry

okre

Ğlony, a aktualna zawartoĞü informacyjna drzewa nie ma na niego wpáywu.

W niektórych zastosowaniach zachodzi potrzeba sterowania przeszukiwaniem
w celu osi

ągniĊcia lepszego rozwiązania. W takim przypadku metoda nie

ogranicza si

Ċ wyborem pierwszego wĊzáa z listy do_sprawdzenia, lecz

wybierany jest taki w

Ċzeá, który wedáug pewnego kryterium jest najbardziej

odpowiedni, aby przeszukiwanie by

áo kontynuowane w kierunku tego wáaĞnie

w

Ċzáa. MoĪna np. zastosowaü kryterium polegające na wyborze wĊzáa

„najbardziej podobnego“ do poszukiwanego. Taki sposób post

Ċpowania jest

nazywany przeszukiwaniem sterowanym, a zastosowana strategia nosi nazw

Ċ

najpierw najlepszy (BF - best first).

Wybór „najbardziej podobnego“ w

Ċzáa w drzewie przeszukiwaĔ moĪna

przedstawi

ü na przykáadzie ukáadanki z rys.3.23. RozwaĪymy dwa stany

uk

áadanki pokazane na rys.3.27.

2

8

1

6

3

4

5

7

1

2

3

5

4

8

6

7

stan aktualny

stan docelowy

Rys.3.27 Aktualny i docelowy stan

uk

áadanki.

Aby oceni

ü podobieĔstwo stanów aktualnego i docelowego wprowadzimy

miar

Ċ podobieĔstwa (odlegáoĞci) pomiĊdzy stanami. Przyjmuje siĊ nastĊpujące

ustalenia:
1. Dla ka

Īdego segmentu ukáadanki wprowadza siĊ wagĊ równą liczbie

pozycji o jak

ą jest on odlegáy od swojej pozycji docelowej.

- 81 -

2. Do wagi segmentu z pkt.1 dodaje si

Ċ 3, jeĞli segment jest w pozycji

Ğrodkowej oraz 6, jeĞli jest on na obrzeĪach i nie poprzedza segmentu, który
docelowo po nim nast

Ċpuje.

Stosuj

ąc te ustalenia moĪna okreĞliü odlegáoĞü stanów aktualnego od

docelowego z rys.3.27. Wyniki zamieszczono w tab.3.1.

Segment

Naliczona waga

1

2+6=8

Tab.3.1 Tabela naliczania odleg

áoĞci

stanów uk

áadanki z rys.3.27.

2

1+6=7

3

1+6=7

4

2+6=8

5

0+6=6

6

1+3=4

7

0+6=6

.

8

2+0=2

Odleg

áoĞü stanów

(suma)

48

Podobne oceny odleg

áoĞci stanu aktualnego od docelowego mogą posáuĪyü jako

kryterium wyboru drogi w drzewie przeszukiwa

Ĕ i tym samym stanowiü

podstaw

Ċ przeszukiwania sterowanego.

3.3.4 Przeszukiwanie pe

áne

Omawiane dotychczas algorytmy by

áy tak skonstruowane, Īe przeszukiwanie

ko

Ĕczyáo siĊ z chwilą napotkania pierwszego wĊzáa, który speániaá zadane

kryterium. Mo

Īna jednak postawiü wymóg wyszukania wszystkich wĊzáów

spe

ániających to kryterium, a zatem kontynuowaü przeszukiwanie w caáej

strukturze. Taki sposób post

Ċpowania okreĞlimy jako przeszukiwanie peáne,

a jego wynikiem jest w przypadku ogólnym lista wyszukanych w

Ċzáów.

Realizacja przeszukiwania pe

ánego wymagaáaby niewielkiej modyfikacji

algorytmu DRZEWO-WSZERZ, polegaj

ącej na wprowadzeniu listy wynik, do

której po kolei by

áyby dodawane wĊzáy speániające kryterium przeszukiwania.

Przeszukiwanie ko

Ĕczyáoby siĊ dopiero z chwilą wyczerpania listy wĊzáów

do_sprawdzenia.

- 82 -

background image

3.3.5

Generowanie dróg rozwi

ązaĔ

Rozwa

Īymy teraz problem poszukiwania drogi pomiĊdzy dwoma zadanymi

w

Ċzáami, tzn. otrzymania peánej listy wĊzáów wystĊpujących podczas

przechodzenia od jednego w

Ċzáa do drugiego. Na przykáad drogĊ pomiĊdzy

w

Ċzáami A i J w drzewie na rys.3.28 moĪna zapisaü w postaci listy wĊzáów

(A B F J).

A

D

B

F

E

C

H

G

I

J

K

L

Rys.3.28 Drzewo z zaznaczon

ą drogą od wĊzáa A do wĊzáa J.

Szczególne znaczenie ma poszukiwanie drogi w drzewach, w których korze

Ĕ

reprezentuje pewien stan pocz

ątkowy a synowie dowolnego wĊzáa moĪliwe

stany osi

ągane z wĊzáa-rodzica w wyniku wykonania elementarnej operacji.

Za

áóĪmy, Īe poszukujemy w drzewie wĊzáa reprezentującego pewien stan

docelowy okre

Ğlany jako rozwiązanie. W takim przypadku nie wystarcza tylko

stwierdzenie, czy poszukiwane rozwi

ązanie istnieje, lecz naleĪy podaü drogĊ

w drzewie przeszukiwa

Ĕ od stanu początkowego (korzenia) do rozwiązania.

Droga ta wyznacza list

Ċ elementarnych operacji potrzebnych do przejĞcia od

stanu pocz

ątkowego do rozwiązania. Ten rodzaj przeszukiwania okreĞlimy jako

generowanie dróg rozwi

ązaĔ.

W przypadku uk

áadanki elementarną operacją jest dozwolone, pojedyncze

przesuni

Ċcie segmentu. Algorytm, który automatycznie generuje rozwiązanie

dla uk

áadanki powinien zwracaü w wyniku listĊ kolejnych konfiguracji

segmentów, z których pierwsza jest stanem pocz

ątkowym, ostatnia stanem

docelowym, a ka

Īde dwie sąsiednie powinny byü osiągalne jedna z drugiej przy

pomocy elementarnej operacji. Za

áóĪmy, Īe naleĪy znaleĨü rozwiązanie dla

uk

áadanki w sytuacji pokazanej na rys.3.29.

- 83 -

8

1

2

6

7

5

3

4

8

1

2

3

7

5

6

4

stan pocz

ątkowy

stan docelowy

Rys.3.29 Aktualny i docelowy stan

uk

áadanki w zadaniu poszukiwania

drogi rozwi

ązania.

Przyk

áadem drogi rozwiązania otrzymanej na podstawie drzewa z rys.3.24. jest

sekwencja stanów uk

áadanki pokazana na rys.3.30.

8

1

2

3

7

5

6

4

8

1

2

6

7

5

3

4

8

1

2

6

7

5

3

4

8

6

2

1

7

5

3

4

Rys.3.30 Droga rozwi

ązania dla sytuacji z rys.3.29.

Pytania kontrolne

1. Poda

ü definicjĊ:

a) drzewa skierowanego;
b) drzewa nieskierowanego.

2. Wyja

Ğniü nastĊpujące pojĊcia:

a) rodzic i syn w

Ċzáa;

b) przodek i potomek w

Ċzáa;

c) korze

Ĕ, poddrzewo, liĞü;

d) g

áĊbokoĞü i wysokoĞü wĊzáa oraz wysokoĞü drzewa;

e) drzewo uporz

ądkowane i drzewo binarne;

f) regularne drzewo binarne;
g) pe

áne drzewo binarne.

3. Omówi

ü tablicową reprezentacjĊ drzew binarnych.

4. Omówi

ü sposoby odwiedzania wierzchoáków drzewa binarnego.

- 84 -

background image

5.

Przedstawi

ü sposoby reprezentacji drzew za pomocą struktur

wska

Ĩnikowych.

6.

Poda

ü definicjĊ drzewa przeszukiwaĔ binarnych oraz omówiü podstawowe

operacje w drzewach BST.

7. Poda

ü sposób reprezentowania oraz podstawową wáasnoĞü kopca.

8. Omówi

ü procedury:

a) przywracania w

áasnoĞci kopca;

b) budowania kopca.

9.

Omówi

ü kolejkĊ priorytetową oraz operacje:

a) usuwania maksymalnego elementu;
b) wstawiania nowego elementu.

10. Scharakteryzowa

ü dwa podstawowe typy zadaĔ przeszukiwania w

drzewach.

11. Omówi

ü strategie przeszukiwania:

a) wszerz (breadth-first),
b) w g

áąb (depth-first),

c) najpierw najlepszy (best-first).

Zadania

1. Napisa

ü rekursywne procedury przechodzenia drzewa binarnego w

porz

ądkach:

a) preorder; b) postorder; c) inorder.

Dla ka

Īdego z punktów a), b) i c) rozwaĪyü dwa warianty: i) drzewo jest

reprezentowane tablicowo; ii) drzewo jest reprezentowane za pomoc

ą

struktur wska

Ĩnikowych.

2. Wprowadzimy nast

Ċpujące pojĊcia:

W

Ċzáem wewnĊtrznym nazywamy dowolny wĊzeá drzewa nie bĊdący

li

Ğciem. StopieĔ wĊzáa to liczba jego synów. Rząd drzewa wynosi k, jeĞli

stopie

Ĕ dowolnego wĊzáa nie przekracza k. Peáne drzewo rzĊdu k, to

- 85 -

drzewo rz

Ċdu k, w którym wszystkie liĞcie mają tĊ samą gáĊbokoĞü, a

wszystkie w

Ċzáy wewnĊtrzne mają stopieĔ k.

Wyprowadzi

ü wzór na liczbĊ wĊzáów peánego drzewa rzĊdu k, jeĞli jego

wysoko

Ğü wynosi h.

3. Napisa

ü procedury wykonania nastĊpujących operacji na drzewach BST:

a)

wyszukiwanie maksymalnego elementu;

b)

wyszukiwanie poprzednika zadanego w

Ċzáa;

c)

usuwanie zadanego w

Ċzáa.

4. Napisa

ü procedurĊ przeszukiwania drzewa w gáąb.

5. Napisa

ü procedurĊ budowania drzewa przeszukiwaĔ binarnych z elementów

uporz

ądkowanej tablicy jednowymiarowej.

- 86 -

background image

4 Sortowanie

4.1 Wprowadzenie

Sortowanie polega na zmianie kolejno

Ğci elementów pewnego ciągu tak, aby

zosta

áy one ustawione w porządku niemalejącym lub nierosnącym. W zbiorze,

do którego nale

Īą elementy ciągu, powinien byü okreĞlony porządek.

Definicja 4.1

Cz

ĊĞciowym porządkiem na zbiorze S nazywamy relacjĊ R, która posiada

nast

Ċpujące wáaĞciwoĞci:

x ZwrotnoĞü. Dla dowolnego

S

a



, zachodzi

.

aRa

x PrzechodnioĞü. Dla dowolnych

S

c

b

a



,

,

, zachodzi: je

Ğli

i

to

.

aRb

bRc

aRc

x AntysymetrycznoĞü. JeĞli

i

bRa

to

aRb

b

a

.

Przyk

áadami czĊĞciowych porządków są: relacja d w zbiorze liczb caákowitych

oraz relacja

Ž dla zbiorów.

Definicja 4.2

Ca

ákowitym (liniowym) porządkiem na zbiorze S nazywamy czĊĞciowy

porz

ądek R na S, taki, Īe dla dowolnych

S

b

a



,

, zachodzi

aRb

albo

.

bRa

Relacja

d jest przykáadem liniowego porządku w zbiorze liczb caákowitych,

natomiast relacja

Ž dla zbiorów nie jest liniowym porządkiem.

Definicja 4.3

Niech S b

Ċdzie zbiorem, w którym jest okreĞlony liniowy porządek d, a

n

a

a

a

,...,

,

2

1

ci

ągiem elementów z S. Zadaniem sortowania jest wyznaczenie

permutacji, tj. pewnej kolejno

Ğci

'

'

2

'

1

,...,

,

n

a

a

a

, zadanych n elementów takiej,

Īe

- 87 -

'

'

2

'

1

...

n

a

a

a

d

d

d

.

Rozwa

Īymy dwie nastĊpujące klasy algorytmów sortowania (rys.4.1):

1.

Algorytmy oparte wy

áącznie na porównywaniu sortowanych elementów.

Dla takich algorytmów wyka

Īemy, Īe do posortowania ciągu záoĪonego z n

elementów potrzeba co najmniej nlgn porówna

Ĕ.

2. Algorytmy korzystaj

ące z pewnych wáasnoĞci sortowanych elementów (np.

z faktu,

Īe sortowane liczby są jednostajnie rozáoĪone w przedziale

>

.

Dla takich algorytmów nie obowi

ązuje dolna granica

1

,

0

n

n lg

:

.

Algorytmy sortowania

Oparte wy

áącznie

na porównywaniu

sortowanych elementów

Wykorzystuj

ące

w

áaĞciwoĞci

sortowanych elementów

Rys.4.1 Klasy algorytmów

sortowania.

Inny podzia

á algorytmów sortowania moĪe byü dokonany ze wzglĊdu na uĪycie

pami

Ċci. WyróĪniamy wtedy:

x

x

algorytmy wewn

Ċtrzne, gdy dane są przechowywane wyáącznie w pamiĊci

wewn

Ċtrznej,

algorytmy zewn

Ċtrzne, gdy w przewaĪającej czĊĞci dane znajdują siĊ poza

pami

Ċcią wewnĊtrzną.

Je

Ğli sortowanie jest czĊĞcią innego algorytmu, wówczas liczba sortowanych

elementów nie jest zwykle du

Īa, co pozwala je zmieĞciü w pamiĊci

wewn

Ċtrznej. Z kolei sortowanie zewnĊtrzne dotyczy gáównie takich

zastosowa

Ĕ, jak operacje w systemach ksiĊgowych, gdzie danych jest zwykle

znacznie wi

Ċcej, niĪ moĪe pomieĞciü pamiĊü wewnĊtrzna.

- 88 -

background image

4.2 Algorytmy oparte na porównaniach

4.2.1 Drzewa decyzyjne

Rozwa

Īymy ponownie algorytm sortowania przez wstawianie (kod K.4.1).

K.4.1

SORT-WSTAW(A)
1

dla

j

m2 do length[A]

2

wykonuj

{ key

m A[j]

3

 Wstaw A[j] do posortowanego ci

ągu A[1..j-1]

4

i

m j-1

5

dopóki

i>0 i A[i]>key

6

wykonuj

{ A[i+1]

m A[i]

7

i

m i-1 }

8

A[i+1]

m key }

Jest to efektywny algorytm w przypadku sortowania niewielkiej liczby
elementów, a jego dzia

áanie moĪna porównaü do ukáadania talii kart w rĊku.

Zaczynaj

ąc od „pustej” rĊki dokáadamy kolejne karty do juĪ uporządkowanej

talii w r

Ċku tak, aby po dodaniu karty byáy nadal uporządkowane. Elementy

tablicy A[1..j-1] reprezentuj

ą (uporządkowane) karty trzymane w rĊce, a

elementy A[j+1..n] reprezentuj

ą nieuporządkowany stos kart na stole. Indeks j

wskazuje na kart

Ċ aktualnie wstawianą do talii. Indeks ten, począwszy od

warto

Ğci 2, przesuwa siĊ w tablicy w stronĊ rosnących indeksów. W kaĪdej

iteracji p

Ċtli zewnĊtrznej (linie 1-8) pobierany jest z tablicy element A[j].

Nast

Ċpnie w pĊtli wewnĊtrznej (linie 5-7) jest poszukiwane wáaĞciwe miejsce

dla elementu A[j] w ju

Ī uporządkowanej czĊĞci tablicy. W tym celu, począwszy

od pozycji j-1, elementy tablicy s

ą przemieszczane w stronĊ rosnących

indeksów dopóty, a

Ī nie „zwolni” siĊ miejsce, w którym powinien byü

umieszczony element A[j]. Sortowanie tablicy

3

,

1

,

6

,

4

,

2

,

5

A

za pomoc

ą

opisywanego algorytmu przedstawiono na rys.4.2.

- 89 -

5

2

4

6

1

3

2

5

4

6

1

3

2

4

5

6

1

3

2

4

5

6

1

3

1

2

4

5

6

3

1

2

3

4

5

6

P o s o r t o w a n e

A[1] A[2] A[3] A[4] A[5] A[6]

Rys.4.2 Sortowanie przez wstawianie.

Sortowanie przez wstawianie jest przyk

áadem sortowania wewnĊtrznego, a

algorytm jest oparty wy

áącznie na porównaniach sortowanych elementów. W

takich algorytmach ustalenie wzgl

Ċdnego poáoĪenia elementów

oraz

jest

mo

Īliwe za poĞrednictwem porównania

i

a

j

a

j

i

a

a

d

, a do ilustracji wykonywanych

porówna

Ĕ wygodnie jest uĪyü struktury nazywanej drzewem decyzyjnym. Na

rysunku 4.3 przedstawiono drzewo decyzyjne odpowiadaj

ące algorytmowi

sortowania ci

ągu

3

2

1

,

,

a

a

a

.

a

1

: a

2

a

2

: a

3

a

1

: a

3

a

1

: a

3

²

¢ a

1

a

2

,

, a

3

²

¢ a

2

a

1

,

, a

3

a

2

: a

3

²

¢ a

1

a

3

,

, a

2

²

¢ a

3

a

1

,

, a

2

²

¢ a

2

a

3

,

, a

1

²

¢ a

3

a

2

,

, a

1

d

!

d

d

d

d

!

!

!

!

Rys.4.3 Drzewo decyzyjne dla sortowanie 3-ch elementów.

Drzewo decyzyjne pokazuje zatem porównania wykonywane przez algorytm
sortuj

ący dla ustalonego rozmiaru danych wejĞciowych. Inne aspekty

algorytmu, jak sterowanie i przep

áyw danych nie są tutaj uwzglĊdniane.

- 90 -

background image

Ka

Īdy wĊzeá wewnĊtrzny odpowiada porównaniu elementów

oraz

. Z ka

Īdym liĞciem drzewa jest natomiast związana pojedyncza

permutacja ci

ągu wejĞciowego. Wykonanie algorytmu polega na przejĞciu od

korzenia do jednego z li

Ğci, a dojĞcie do liĞcia oznacza, Īe algorytm znalazá juĪ

uporz

ądkowanie (permutacjĊ) elementów. Sortowanie na podstawie drzewa

decyzyjnego z rys.4.3 mo

Īna przeĞledziü zakáadając

i

a

j

a

3

,

1

d

d

j

i

.

0

,

2

,

1

3

2

1



a

a

a

W tym przypadku algorytm wykona si

Ċ „wzdáuĪ” ĞcieĪki:

2

3

1

3

1

3

2

2

1

,

,

:

:

:

a

a

a

a

a

a

a

a

a

o

o

o

.

4.2.2

Dolne ograniczenie na czas sortowania

Jak wynika z rys.4.3, d

áugoĞü najdáuĪszej ĞcieĪki od korzenia drzewa

decyzyjnego do li

Ğcia odpowiada liczbie porównaĔ dokonywanej przez

algorytm sortuj

ący w przypadku pesymistycznym. JeĞli zatem uda siĊ okreĞliü

dolne

ograniczenie na wysoko

Ğü drzew decyzyjnych, to bĊdzie ono

jednocze

Ğnie dolnym ograniczeniem na czas dziaáania algorytmów sortujących

wy

áącznie za pomocą porównaĔ. Oceny dolnego ograniczenia moĪna dokonaü

korzystaj

ąc ze sformuáowanego i udowodnionego dalej twierdzenia [5].

Twierdzenie 4.1

Ka

Īde drzewo decyzyjne odpowiadające algorytmowi poprawnie sortującemu n

elementów ma wysoko

Ğü

n

n lg

:

.

Dowód

Rozwa

Īymy drzewo decyzyjne o wysokoĞci h odpowiadające algorytmowi

sortuj

ącemu n elementów. Liczba permutacji dla ciągu záoĪonego z n

elementów wynosi n!, drzewo to ma zatem n! li

Ğci. PoniewaĪ drzewo binarne o

wysoko

Ğci h nie moĪe mieü wiĊcej niĪ

li

Ğci stąd

h

2

.

h

n

2

!

d

Logarytmuj

ąc obustronnie ostatnią nierównoĞü otrzymujemy

(4.1)

!

lg n

h

t

- 91 -

Dalej skorzystamy z nast

Ċpującego wzoru Stirlinga

¸¸

¹

·

¨¨

©

§

¸

¹

·

¨

©

§

4



¸

¹

·

¨

©

§

n

e

n

n

n

n

1

1

2

!

S

,

z którego wynika,

Īe

n

e

n

n

¸

¹

·

¨

©

§

!

!

(4.2)

gdzie

jest podstaw

ą logarytmu naturalnego. UwzglĊdniając

nierówno

Ğü (4.2) otrzymujemy na podstawie (4.1):

...

71828

,

2

e

n

n

e

n

n

n

e

n

h

n

lg

lg

lg

lg

:



¸

¹

·

¨

©

§

t

.

Uwaga

W wyniku dokonanej wcze

Ğniej analizy algorytmu sortowania przez wstawianie

otrzymano z

áoĪonoĞü pesymistyczną

2

n

O

. Oznacza to,

Īe górne

ograniczenie na czas dzia

áania tego algorytmu nie jest równe dolnej granicy

z naszego twierdzenia. Mówimy,

Īe nie jest to asymptotycznie

optymalny algorytm sortuj

ący wyáącznie za pomocą porównaĔ.

n

n lg

:

4.2.3

Algorytmy asymptotycznie optymalne

Rozwa

Īymy dwa przykáady algorytmów asymptotycznie optymalnych:

sortowanie przez kopcowanie i sortowanie przez scalanie.

Sortowanie przez kopcowanie (heapsort)

Algorytm sortowania przez kopcowanie (kod K.4.2) u

Īywa kopca

zbudowanego z elementów sortowanej tablicy A.

K.4.2

SORT-KOPCOW(A)
1 KOPIEC-BUDUJ(A)
2

dla

i

m length[A] w_dóá_do 2

3

wykonuj

{ zamie

Ĕ A[1]lA[i]

- 92 -

background image

4

heap-size[A]

m heap-size[A]-1

5

KOPIEC-PRZYWR(A,1) }

A

3

1

2

3

4

5

6

7

8

9

10

11

2

4

1

14

16

10

8

7

9

Rys.4.4 Tablica elementów do posortowania.

a)

16

14

7

8

10

9

3

4

2

1

b)

14

8

7

4

10

9

3

1

2

16

c)

10

8

7

4

9

1

3

14

2

16

d)

9

8

7

4

3

1

2

14

10

16

e)

8

7

2

4

3

1

9

14

10

16

f)

7

4

2

1

3

8

9

14

10

16

g)

4

2

7

1

3

8

9

14

10

16

h)

3

2

7

4

1

8

9

14

10

16

i)

2

1

7

4

3

8

9

14

10

16

j)

1

2

7

4

3

8

9

14

10

16

- 93 -

Rys.4.5 Sortowanie przez kopcowanie tablicy z rys.4.4.

Algorytm ten rozpoczyna dzia

áanie uĪywając podanej wczeĞniej procedury

budowania kopca z n-elementowej tablicy A. Poniewa

Ī najwiĊkszy element

znajduje si

Ċ w korzeniu A[1], stąd moĪe on zostaü umieszczony na swoim

miejscu, tj. na ko

Ĕcu tablicy A przez zamianĊ miejscami z A[n]. Po tej zamianie

odrzucamy element A[n] zmniejszaj

ąc rozmiar kopca o 1 i przywracamy

w

áasnoĞü kopca dla pozostaáych elementów. Taka operacja jest nastĊpnie

powtarzana dla kopca o rozmiarze n-1, n-2, itd., a

Ī otrzymamy kopiec o

rozmiarze 2.

Dzia

áanie algorytmu sortowania przez kopcowanie zilustrowano na przykáadzie

sortowania tablicy A zawieraj

ącej 10 liczb (rys.4.4). Rysunki 4.5ay4.5j

pokazuj

ą postaü kopca oraz fragment posortowanej tablicy na początku

kolejnych iteracji p

Ċtli dla w linii 2.

Algorytm ten wykonuje funkcj

Ċ budowania kopca dziaáającą w czasie

, a

nast

Ċpnie dokonuje n-1 wywoáaĔ funkcji przywracania wáaĞciwoĞci kopca, z

których ka

Īde zajmuje czas

n

O

n

O lg

. St

ąd ogólny czas dziaáania caáej

procedury sortowania przez kopcowanie wynosi

n

n

O

lg

.

Metoda „dziel i zwyci

ĊĪaj” i sortowanie przez scalanie

Stosowanie rekurencji sprzyja zwi

Ċzáemu i eleganckiemu zapisowi algorytmów,

lecz samo w sobie nie zwi

Ċksza ich efektywnoĞci (np. w sensie skrócenia czasu

oblicze

Ĕ). JeĞli jednak rekurencjĊ dopeániü pewnymi dodatkowymi zabiegami,

jak równowa

Īenie oraz zastosowanie metody okreĞlanej jako „dziel i

zwyci

ĊĪaj” moĪna uzyskaü bardziej efektywne algorytmy.

W podej

Ğciu „dziel i zwyciĊĪaj” wystĊpuje rekursja, przy czym kaĪdy poziom

rekursji ma nast

Ċpującą strukturĊ:

dziel

-

dzielimy problem na podproblemy;

zwyci

ĊĪaj

-

na tym etapie rozwi

ązujemy podproblemy rekurencyjnie

wykorzystuj

ąc metodĊ „dziel i zwyciĊĪaj”, chyba, Īe są one

tak ma

áych rozmiarów, Īe nie wymagają zastosowania

- 94 -

background image

rekursji;

po

áącz

-

áączymy rozwiązania podproblemów, aby otrzymaü
rozwi

ązanie caáego problemu.

Metod

Ċ „dziel i zwyciĊĪaj” zaprezentujemy na przykáadzie algorytmu

sortowania przez scalanie dzia

áającego w czasie

n

n lg

4

. Dla uproszczenia

b

Ċdziemy zakáadaü, Īe sortowanym ciągiem jest

n

x

x

x

,...,

,

2

1

,

,

k

n

2

N

k



a poszukuje si

Ċ permutacji

n

x

x

x

c

c

c

,...,

,

2

1

elementów ci

ągu początkowego takich, Īe

n

x

x

x

c

d

d

c

d

c

...

2

1

.

Etapy algorytmu s

ą nastĊpujące:

1. Dziel

Dzielimy n-elementowy ci

ąg na dwa podciągi po n/2

elementów ka

Īdy.

2. Zwyci

ĊĪaj

Sortujemy otrzymane podci

ągi, uĪywając rekurencyjnie

sortowania przez scalanie. Je

Ğli na którymĞ poziomie rekursji

otrzymujemy do posortowania ci

ąg jednoelementowy, wówczas

nie nast

Ċpuje dalsze zagáĊbianie wywoáaĔ rekursywnych.

3. Po

áącz

àączymy ciągi posortowane na niĪszych poziomach rekursji w
jeden posortowany ci

ąg.

G

áówna procedura sortowania zostaáa przedstawiona jako kod K.4.3.

K.4.3

SORT-SCALANIE(A, p, r)
1 je

Ğli p<r

2 to { q

m ¬(p+r)/2¼

3 SORT-SCALANIE(A, p, q)
4 SORT-SCALANIE(A, q+1, r)
5 SCALAJ(A, p, q, r) }

- 95 -

Procedura SORT-SCALANIE(A,p,r) sortuje podtablic

Ċ A[p..r] záoĪoną z m

elementów (m=r-p+1). Je

Ğli

r

p

t

, to tablica jest ju

Ī posortowana i nie

nast

Ċpuje dalsze zagáĊbianie wywoáaĔ rekursywnych. W przeciwnym razie

dzieli si

Ċ tablicĊ

na dwie podtablice:

>

r

p

A ..

@

>

@

q

p

A ..

zawieraj

ącą

elementów oraz

zawieraj

ącą

ª

º

2

/

m

> @

r

q..

A

¬

¼

2

/

m

elementów. Dla tak otrzymanych

tablic wywo

áuje siĊ procedurĊ sortowania przez scalanie (linie 3 i 4). NastĊpnie

posortowane „po

áówki“ powinny zostaü poáączone (scalone) tak, aby w wyniku

otrzyma

ü takĪe posortowaną tablicĊ (linia 5). Opracowanie procedury scalającej

pozostawia si

Ċ czytelnikowi (zob zad.2 na koĔcu rozdziaáu). Aby zatem

posortowa

ü tablicĊ

> @ > @ > @

> @

>

@

A

length

,

1

A

,...,

3

A

A

,

2

A

A

, procedur

Ċ sortowania

wywo

áuje siĊ nastĊpująco: SORT-SCALANIE(A,1,length[A]).

Schemat sortowania przez scalanie dla

6

,

2

,

3

,

1

,

6

,

4

,

2

,

5

A

pokazano na

rys.4.6.

1 2 2 3 4 5 6 6

scal

2 4 5 6

1 2 3 6

2 5

4 6

1 3

2 6

scal

scal

scal

scal

scal

scal

5

2

4

6

1

3

2

6

Rys.4.6 Sortowanie przez scalanie.

Ocenimy teraz z

áoĪonoĞü czasową algorytmu sortowania przez scalanie. Jest to

algorytm rekurencyjny, który wykorzystuje metod

Ċ „dziel i zwyciĊĪaj”. Czas

dzia

áania

T(n) takich algorytmów mo

Īna opisaü zaleĪnoĞcią rekurencyjną

postaci:

¯

®

­

!





d

4

s

n

n

C

n

D

b

n

aT

s

n

n

T

,

/

,

1

(4.3)

Zapis ten oznacza,

Īe jeĞli problem jest dostatecznie maáy (rozmiar zadania nie

przekracza pewnej sta

áej s), wówczas jego rozwiązanie zajmuje staáy czas

.

Je

Ğli natomiast dzielimy problem na a podproblemów i kaĪdy z nich jest

1

4

- 96 -

background image

rozmiaru n/b, to czas rozwi

ązania tych podproblemów wyniesie

. Do

tej wielko

Ğci naleĪy dodaü czas

b

n

aT

/

n

D

przeznaczony na dzielenie problemu na

podproblemy oraz czas scalania

n

!1

n

!1

n

C

.

c

n lg

W przypadku sortowania przez scalanie zale

ĪnoĞü rekurencyjna (4.3) ma

posta

ü:

(4.4)

¯

®

­

4



4

,

2

/

2

1

,

1

n

n

T

n

n

T

gdzie sk

áadnik

oznacza czas scalania, a czas dzielenia, jako sta

áy

pomini

Ċto. ZáoĪonoĞü obliczeniową algorytmu sortowania przez scalanie moĪna

otrzyma

ü rozwiązując równanie rekurencyjne (4.4). Rozwiązanie to moĪna

otrzyma

ü wprost, jeĞli skorzystaü z podanego niĪej twierdzenia [5].

n

4

Twierdzenie 4.2

Niech a,b,c b

Ċdą nieujemnymi staáymi. Rozwiązanie równania rekurencyjnego

¯

®

­



,

/

1

,

bn

c

n

aT

n

b

n

T

dla n b

Ċdących potĊgą liczby c ma postaü


°

¯

°

®

­

!



,

,

lg

,

log

c

a

n

O

a

n

n

O

c

a

n

O

n

T

a

c

.

Z powy

Īszego twierdzenia, którego dowód pominiemy, wynika, Īe záoĪonoĞü

obliczeniowa

algorytmu sortowania przez scalanie wynosi

O

.

Uwzgl

Ċdniając wczeĞniej udowodnione twierdzenie 4.1 otrzymujemy, Īe

z

áoĪonoĞü ta wynosi

.

n

n

n lg

4

4.3 Sortowanie w czasie liniowym

Przedstawimy dwa algorytmy, dla których nie obowi

ązuje dolna granica na czas

sortowania

n

n lg

:

, jak to ma miejsce w przypadku algorytmów opartych

wy

áącznie na porównaniach. Prezentowane tutaj algorytmy oprócz porównaĔ

- 97 -

wykorzystuj

ą pewne specyficzne wáaĞciwoĞci sortowanych elementów, przy

czym mo

Īe siĊ zdarzyü, Īe porównania nie są w ogóle konieczne.

4.3.1

Sortowanie przez zliczanie

W algorytmie sortowania przez zliczanie zak

áadamy, Īe kaĪdy z n sortowanych

elementów jest liczb

ą caákowitą z przedziaáu

. Je

Ğli

k

..

1

n

O

k

, to wtedy

sortowanie dzia

áa w czasie

n

O

. Idea algorytmu polega na okre

Ğleniu dla

ka

Īdego elementu x, ile elementów jest mniejszych lub równych x. Mając tĊ

liczb

Ċ, moĪemy okreĞliü dokáadną pozycjĊ x w posortowanym ciągu. ProcedurĊ

sortowania przez zliczanie przedstawia kod K.4.4.

K.4.4

SORT-ZLICZANIE(A, B, k)

1

dla

i

m1 do k

2

wykonuj

C[i]

m 0

3

dla

j

m1 do length[A]

4

wykonuj

C[A[j]]

m C[A[j]] + 1

5

 C[i] zawiera teraz liczb

Ċ elementów równych i

6

dla

i

m2 do k

7

wykonuj

C[i]

m C[i] + C[i-1]

8

 C[i] zawiera teraz liczb

Ċ elementów mniejszych lub równych i

9

dla

j

m length[A] w_dóá_do 1

10

wykonuj

{ B[C[A[j]]]

m A[j]

11

C[A[j]]

m C[A[j]] – 1 }

W procedurze SORT-ZLICZANIE przyj

Ċto, Īe dane wejĞciowe są elementami

tablicy

,

. Tablica

> @

n

A ..

1

> @

A

length

n

> @

n

B ..

1

jest tablic

ą wyjĞciową, gdzie

zostan

ą umieszczone posortowane elementy, a tablica

> @

k

..

1

C

jest tablic

ą

pomocnicz

ą. W liniach 1-2 tablica C jest zerowana, natomiast operacje w

liniach 3-4 prowadz

ą do zapisu w kaĪdym elemencie

> @

i

C

liczby ca

ákowitej

odpowiadaj

ącej iloĞci elementów tablicy wejĞciowej równych i. NastĊpnie w

liniach 6-7 jest wyznaczana i zapisywana w

> @

i

C

liczba elementów tablicy

wej

Ğciowej mniejszych lub równych i. Ostatecznie w liniach 9-11 wszystkie

elementy zostaj

ą rozmieszczone na wáaĞciwych miejscach w tablicy

.

B

Dzia

áanie algorytmu K.4.4 zilustrujemy na przykáadzie sortowania tablicy

4

,

1

,

4

,

3

,

1

,

4

,

6

,

3

A

,

- 98 -

background image

dla której

8

n

oraz

.

6

k

Po wykonaniu linii 4 tablice A i C maj

ą postaü pokazaną na rys.4.7a, natomiast

po wykonaniu linii 7 tablica C zostaje wype

ániona w sposób przedstawiony na

rys.4.7b. Rysunki 4.7c-4.7j pokazuj

ą postaü tablic B i C po kolejnych iteracjach

wykonywanych w liniach 9-11.

a)

3 6 4 1 3 4 1 4

1

3 4 5 6 7 8

2

A

C

2 0 2 3 0 1

1

3 4 5 6

2

b)

C

2 2 4 7 7 8

1

3

4 5 6

2

c)

j=8

4

1

3

4 5 6 7

2

B

C

8

2 2 4 6 7 8

1

3

4 5 6

2

d)

j=7

4

1

3

4 5 6 7

2

B

C

8

1 2 4 6 7 8

1

3

4 5 6

2

1

e)

j=6

4

1

3

4 5 6 7

2

B

C

8

1 2 4 5 7 8

1

3

4 5 6

2

1

4

f)

j=5

4

1

3

4 5 6 7

2

B

C

8

1 2 3 5 7 8

1

3

4 5 6

2

1

4

3

g)

j=4

4

1

3

4 5 6 7 8

2

B

C

0 2 3 5 7 8

1

3

4 5 6

2

1

4

3

1

h)

j=3

4

1

3

4 5 6 7 8

2

B

C

0 2 3 4 7 8

1

3

4 5 6

2

1

4

3

1

4

i)

j=2

4

1

3

4 5 6 7

2

B

C

8

0 2 3 4 7 7

1

3

4 5 6

2

1

4

3

1

4

6

j)

j=1

4

1

3

4 5 6 7 8

2

B

C

0 2 2 4 7 7

1

3

4 5 6

2

1

4

3

1

4

3

6

Rys.4.7 Ilustracja algorytmu sortowania przez zliczanie dla tablicy

¢3,6,4,1,3,4,1,4².

- 99 -

Ocenimy czas dzia

áania algorytmu sortowania przez zliczanie. PĊtle w liniach

1-2 oraz 3-4 wymagaj

ą odpowiednio czasów

k

O

oraz

n

O

. Poniewa

Ī

analogiczne wymogi maj

ą pĊtle w liniach 6-7 oraz 9-11, stąd caákowity czas

dzia

áania procedury K.4.4 moĪna zapisaü jako

n

k

O



. Z za

áoĪenia

wynika dalej,

Īe czas ten wynosi

n

O

k

n

O

, a zatem jest ograniczony funkcj

ą

liniow

ą wzglĊdem liczby sortowanych elementów n. Ocena ta Ğwiadczy o duĪej

efektywno

Ğci algorytmu sortowania przez zliczanie.

4.3.2 Sortowanie

kube

ákowe

Algorytm sortowania kube

ákowego równieĪ naleĪy do algorytmów szybkich, tj.

sortuj

ących w czasie liniowym. Podobnie jak w przypadku sortowania przez

zliczanie, tutaj tak

Īe nakáada siĊ ograniczenie na dane wejĞciowe. Polega ono

na za

áoĪeniu, Īe sortowane są liczby wybrane losowo (z rozkáadem

jednostajnym) z przedzia

áu

>

1

..

0

. Procedur

Ċ sortowania kubeákowego

przedstawiono w postaci kodu K.4.5.

K.4.5

SORT-KUBE

àKOWE(A)

1

n

m length[A]

2

dla

i

m1 do n

3

wykonuj

wstaw A[i] do listy B[

¬n A[i]¼]

4

dla

i

m0 do n-1

5

wykonuj

posortuj list

Ċ B[i] przez wstawianie

6 po

áącz listy B[0], B[1],..., B[n-1] w tej kolejnoĞci

Parametrem wej

Ğciowym jest n-elementowa tablica A, której elementy speániają

zale

ĪnoĞü

. Algorytm sortowania zak

áada podziaá przedziaáu

na n podprzedzia

áów jednakowych rozmiarów nazywanych „kubeákami”, a

nast

Ċpnie rozrzucenie n liczb do tych podprzedziaáów. W tym celu jest

wykorzystana tablica list

> @

1

0



d

i

A

>

1

..

0

>

@

1

..

0



n

B

reprezentuj

ących kubeáki. Liczby w

podprzedzia

áach są nastĊpnie sortowane przez wstawianie, a posortowane listy z

ka

Īdego podprzedziaáu áączy siĊ ze sobą.

Dzia

áanie algorytmu zilustrujemy na przykáadzie 10-elementowej tablicy

0,68

;

23

,

0

;

12

,

0

;

21

,

0

;

94

,

0

;

72

,

0

;

26

,

0

;

0,39

;

17

,

0

;

78

,

0

A

.

- 100 -

background image

Rysunek 4.8a przedstawia nieposortowan

ą tablicĊ A, natomiast rys.4.8b tablicĊ

B po wykonaniu p

Ċtli w liniach 4-5 procedury.

0
1
2
3
4

B

5
6

7

8

9

a)

b)

1
2
3
4
5

A

0,78

0,17
0,39
0,26
0,72
0,94

0,21

0,12

0,23

0,68

6
7

8

9

10

0,12

0,17

nil

0,21

0,23

0,39

0,68

0,26

nil

nil

0,72

0,78

nil

nil

0,94

nil

Rys.4.8 Sortowanie kube

ákowe.

Poprawno

Ğü sortowania kubeákowego

W celu wykazania,

Īe algorytm sortowania kubeákowego dziaáa poprawnie,

rozwa

Īa siĊ ([5]) dwa dowolne elementy

> @

i

A

i

> @

j

A

. Je

Ğli podczas sortowania

trafi

ą one do tego samego kubeáka, to w tablicy wynikowej na pewno wystąpią

w poprawnej kolejno

Ğci, poniewaĪ liczby w kaĪdym kubeáku są sortowane

przez wstawianie, a poprawno

Ğü tej metody zakáadamy. ZaáóĪmy zatem, Īe

elementy

> @

i

A

i

trafi

ą do róĪnych kubeáków o numerach odpowiednio

i

i

, a ponadto

i

. Po po

áączeniu kubeáków elementy listy

znajd

ą siĊ

przed elementami listy

> @

j

A

jc



c

c

jc

> @

i

B c

>

j

B

@

c

, a zatem element

> @

i

A

poprzedzi

w ci

ągu

wynikowym. Musi wtedy zachodzi

ü

>

j

A

@

> @

> @

j

A

i

A

d

, co wyka

Īemy metodą „nie

wprost”, zak

áadając, Īe jest przeciwnie. Otrzymujemy wówczas

> @

¬

¼

> @

¬

¼

j

j

nA

i

nA

i

c

t

c

co jest sprzeczne z wcze

Ğniejszym zaáoĪeniem, Īe

i

jc



c

.

Z

áoĪonoĞü sortowania kubeákowego

Mo

Īna równieĪ wykazaü ([5]), Īe czas dziaáania algorytmu sortowania

kube

ákowego jest liniowy wzglĊdem liczby sortowanych elementów. PoniewaĪ

pesymistyczny czas wykonania operacji we wszystkich liniach oprócz linii 5

- 101 -

wynosi

, pozostaje dokona

ü analizy sortowania wszystkich list

zawieraj

ących elementy w kubeákach. Oznaczymy przez

n

zmienn

ą losową odpowiadającą liczbie elementów w kubeáku

.

Pesymistyczny czas sortowania przez wstawianie wynosi

n

O

,...

1

,

0

n

> @

1

,



i

i

B

i

> @

i

B

2

n

O

, a zatem

oczekiwany czas posortowania elementów listy

> @

i

B

wynosi

>

@

2

E

n

O

> @

2

E

i

i

n

O

.

Ocenimy teraz ca

ákowity oczekiwany czas posortowania elementów we

wszystkich kube

ákach, tzn.

.

(4.5)

> @

> @

¸

¹

·

¨

©

§

¦

¦





1

0

2

1

0

2

E

E

n

i

i

n

i

i

n

O

n

O

Mamy n elementów i n list. Poniewa

Ī do kaĪdej listy trafiają elementy z

n

1

cz

ĊĞci caáego przedziaáu

, to prawdopodobie

Ĕstwo tego, Īe dany element

trafi do listy

, jest jednakowe dla wszystkich list i wynosi

>

1

,

0

> @

i

B

n

1

p

.

Zmienna losowa

n

ma zatem rozk

áad dwumianowy z wartoĞcią oczekiwaną

i

> @

1

E

np

n

i

i wariancj

ą

> @

n

p

np

n

i

1

1

1

Var





.

Na podstawie znanej zale

ĪnoĞci dla wartoĞci oczekiwanej i wariancji zmiennej

losowej otrzymujemy

> @

> @

> @

1

1

2

1

1

1

E

Var

E

2

2

2

4









n

n

n

n

n

i

i

i

.

Wynik ten, w po

áączeniu z (4.5), pozwala stwierdziü, Īe czas posortowania

elementów we wszystkich kube

ákach jest liniowy, a zatem oczekiwany czas

sortowania kube

ákowego jest takĪe liniowy.

Pytania kontrolne

1. Poda

ü definicjĊ oraz przykáady porządku czĊĞciowego i porządku

liniowego.

- 102 -

background image

2. Sformu

áowaü ogólnie zadanie sortowania oraz scharakteryzowaü dwie klasy

algorytmów sortowania.

3. Wyja

Ğniü pojĊcia sortowania wewnĊtrznego i zewnĊtrznego.

4. Omówi

ü na przykáadzie uĪycie drzewa decyzyjnego do prezentacji

algorytmu sortowania za pomoc

ą porównaĔ.

5. Poda

ü dolne ograniczenie na pesymistyczny czas sortowania w algorytmach

wykorzystuj

ących tylko porównania i udowodniü jego poprawnoĞü.

6. Przedstawi

ü algorytm sortowania przez wstawianie i oszacowaü jego

z

áoĪonoĞü czasową.

7. Przedstawi

ü algorytm sortowania przez kopcowanie i oszacowaü jego

z

áoĪonoĞü czasową.

8. Na

przyk

áadzie algorytmu sortowania przez scalanie przedstawiü istotĊ

metody „dziel i zwyci

ĊĪaj“.

9. Dla algorytmu sortowania przez scalanie pokaza

ü zastosowanie zaleĪnoĞci

rekurencyjnej do oszacowania czasu dzia

áania algorytmu.

10. Omówi

ü algorytm sortowania przez zliczanie dziaáający w czasie liniowym

i wyja

Ğniü fakt, Īe dla tego algorytmu nie obowiązuje granica

:

.

n

n lg

11. Omówi

ü algorytm sortowania kubeákowego i wykazaü jego poprawnoĞü.

Jaka cecha

áączy algorytmy sortowania przez zliczanie i sortowania

kube

ákowego?

Zadania

1. Skonstruowa

ü drzewo decyzyjne odpowiadające algorytmowi sortowania

przez wstawianie dla ci

ągu

.

4

3

2

1

,

,

,

a

a

a

a

2. Napisa

ü procedurĊ SCALAJ(A,p,q,r) realizującą scalanie posortowanych

tablic

>

@

q

p

A ..

i

w jedn

ą posortowaną tablicĊ

>

r

q

A

..

1



@

>

@

r

p

A ..

, tak, aby

mog

áa ona byü wykorzystana w algorytmie sortowania przez scalanie.

3. Zilustrowa

ü dziaáanie procedury sortowania przez zliczanie dla tablicy

3

,

4

,

2

,

7

,

5

,

4

,

2

,

1

,

3

,

1

,

7

A

.

4. Zilustrowa

ü dziaáanie procedury sortowania kubeákowego dla tablicy

42

,

0

,

0,71

,

53

,

0

,

89

,

0

,

20

,

0

,

39

,

0

,

0,64

,

16

,

0

,

0,13

,

79

,

0

A

.

- 103 -

5 Bibliografia

[1] Aho A.V., Hopcroft J.E., Ullman J.D.: Projektowanie i analiza

algorytmów komputerowych. PWN, 1983.

[2] Anderson J.R., Corbett A.T., Reiser B.J.: Essential LISP.

Addison-Wesley Publishing Company, 1987.

[3] Banachowski L., Diks K., Rytter W.: Algorytmy i struktury

danych. Wydawnictwa Naukowo-Techniczne, 1996.

[4] Banachowski L., Kreczmar A.: Elementy analizy algorytmów.

Wydawnictwa Naukowo-Techniczne, 1982.

[5] Cormen T.H., Leiserson C.E,, Rivest R.L.: Wprowadzenie do

algorytmów. Wydawnictwa Naukowo-Techniczne, 1997.

[6] Drozdek A., Simon D.L.: Struktury danych w j

Ċzyku C.

Wydawnictwa Naukowo-Techniczne, 1996.

[7] Knuth D.E.: Sztuka programowania. Tom 1. Algorytmy

podstawowe. Wydawnictwa Naukowo-Techniczne, 2002.

[8] Winston P.H., Horn B.K.P.: LISP. Third Edition. Addison-Wesley

Publishing Company, 1989.

- 104 -

background image

DODATEK

Zadania na egzaminy i kolokwia

W uzupe

ánieniu zostaną podane przykáadowe zestawy zadaĔ, jakie pojawiaáy

si

Ċ w ostatnich latach na egzaminach i kolokwiach. Przy kaĪdym zadaniu w

nawiasach podano maksymaln

ą liczbĊ punktów, na którą moĪe byü oceniona

prawid

áowa odpowiedĨ. Czas rowiązywania w przeliczeniu na 1 punkt wynosiá

Ğrednio 2 minuty. MoĪliwe jest wystąpienie w róĪnych zestawach podobnych, a
nawet identycznych zada

Ĕ. Pozostawiono je celowo, aby Czytelnik mógá

zmierzy

ü siĊ z „oryginalnymi” zestawami obejmującymi z reguáy odpowiednio

dobrany zakres materia

áu.

Zestaw 1

1. Zdefiniowa

ü jednym zdaniem nastĊpujące pojĊcia:

a) g

áĊbokoĞü wierzchoáka drzewa; (1)

b) operand typu i w j

Ċzyku maszyny RAM; (1)

c) silnie spójny graf skierowany; (1)
d) procedura rekurencyjna; (1)
e) algorytm sortuj

ący w czasie liniowym; (1)

f) asymptotycznie optymalny algorytm sortuj

ący wyáącznie za pomocą

porówna

Ĕ. (1)

2. Napisa

ü rekurencyjną procedurĊ obliczającą n-tą potĊgĊ liczby m (m>0). (2)

3. Rozwa

Īyü nastĊpujący program w jĊzyku maszyny RAM:

LOAD =0
STORE 1
LOAD =1
STORE 2

ET1: LOAD =5

SUB 2
JGTZ Et2
JUMP Et3

Et2: LOAD 1

ADD 2
STORE 1
LOAD 2
ADD =1
STORE 2
JUMP ET1

Et3: WRITE 1

HALT

- 105 -

a) Jaka jest waga logarytmiczna operandu w pierwszej komendzie LOAD? (1)
b) Jaka jest warto

Ğü operandu w komendzie z etykietą Et1? (1)

c) Jakiego typu adres wyst

Ċpuje w komendzie JGTZ? (1)

d) Ile razy wykona si

Ċ komenda ADD 2 ? (1)

e) Poda

ü wynik dziaáania programu (1)

f) Ile rejestrów wykorzystano w obliczeniach ? (1)
g) Jakie zadanie pe

áni tutaj rejestr 0 ? (1)

4. Rozwa

Īyü wyraĪenie: (((2-1)*3)+1).

a) Poda

ü odwrotny zapis polski tego wyraĪenia. (1)

b) Przedstawi

ü ciąg operacji na stosie wykonywanych w trakcie otrzymania

zapisu postfiksowego. (2)

c) Przedstawi

ü ciąg operacji na stosie wykonywanych w trakcie obliczania

warto

Ğci otrzymanego wyraĪenia postfiksowego. (2)

5.

Zak

áadamy Īe liczby: 1, 3, 5, 7, 9, 0 są odpowiednio elementami

A[1],..., A[6] tablicy A.

a) Sporz

ądziü rysunek pokazujący rozmieszczenie tych liczb w wĊzáach

odpowiedniego drzewa binarnego reprezentuj

ącego kopiec zbudowany w

wyniku wywo

áania procedury KOPIEC-BUDUJ(A). (2)

b) Przedstawi

ü rysunek pokazujący stan po usuniĊciu maksymalnego elementu

z kolejki priorytetowej reprezentowanej przez kopiec z p. a). (2)

c) Jak b

Ċdzie wyglądaáa kolejka priorytetowa reprezentowana przez kopiec z p.

a) po wykonaniu operacji dodawania elementu o warto

Ğci 8? (2)

6.

Zak

áada siĊ, Īe tablica A=¢3,4,1,4² jest sortowana przez zliczanie wedáug

nast

Ċpującego algorytmu:

SORT-ZLICZANIE(A, B, k)

1

dla

i

m1 do k

2

wykonuj

C[i]

m 0

3

dla

j

m1 do length[A]

4

wykonuj

C[A[j]]

m C[A[j]] + 1

5

dla

i

m2 do k

6

wykonuj

C[i]

m C[i] + C[i-1]

7

dla

j

m length[A] w_dóá_do 1

8

wykonuj

{ B[C[A[j]]]

m A[j]

9

C[A[j]]

m C[A[j]] – 1 }

a) Jaka jest zawarto

Ğü tablicy C przed wejĞciem do pĊtli w liniach 7-9? (1)

b) Jaka jest zawarto

Ğü tablicy C po wykonaniu procedury? (1)

c) Jaka jest zawarto

Ğü tablicy B po wykonaniu procedury? (1)

d) Jaka jest zawarto

Ğü tablicy A po wykonaniu procedury? (1)

- 106 -

background image

Zestaw 2

1.

Zdefiniowa

ü jednym zdaniem nastĊpujące pojĊcia:

a) z

áoĪonoĞü pamiĊciowa; (1)

b) lista (definicja rekurencyjna); (1)
c) stopie

Ĕ wĊzáa w drzewie; (1)

d) rz

ąd drzewa; (1)

e) procedura rekurencyjna; (1)
f) algorytm sortuj

ący w czasie liniowym. (1)

2.

Napisa

ü w pseudokodzie procedurĊ , która dla i-tego elementu kopca

wypisuje po kolei elementy tworz

ące drogĊ od tego elementu do korzenia

kopca. (2)

3.

Rozwa

Īyü program:

LOAD =1
STORE 1
LOAD =1
STORE 2

ET1: LOAD =4

SUB 2
JGTZ Et2
JUMP Et3

Et2: LOAD 1

MULT 2
STORE 1
LOAD 2
ADD =1
STORE 2
JUMP ET1

Et3: WRITE 1

HALT

a)

Jaka jest waga logarytmiczna drugiej komendy STORE? (1)

b)

Jaka jest warto

Ğü operandu w komendzie z etykietą Et1? (1)

c)

Jakiego typu adres wyst

Ċpuje w komendzie JGTZ? (1)

d)

Ile razy wykona si

Ċ komenda MULT 2 ? (1)

e) Poda

ü wynik dziaáania programu. (1)

f)

Ile rejestrów wykorzystano w obliczeniach? (1)

g) Poda

ü wagĊ logarytmiczną operandu komendy MULT podczas jej ostatniego

wykonania. (1)

4.

Zak

áadamy Īe liczby: 1, 3, 5, 7, 9, 0 są odpowiednio elementami

A[1],..., A[6] tablicy A.

a) Sporz

ądziü rysunek pokazujący rozmieszczenie tych liczb w wĊzáach

odpowiedniego drzewa binarnego reprezentuj

ącego kopiec zbudowany w

wyniku wywo

áania procedury KOPIEC-BUDUJ(A). (2)

- 107 -

b) Przedstawi

ü rysunek pokazujący stan po usuniĊciu maksymalnego elementu

z kolejki priorytetowej reprezentowanej przez kopiec z p. a). (2)

c) Jak b

Ċdzie wyglądaáa kolejka priorytetowa reprezentowana przez kopiec z p.

a) po wykonaniu operacji dodawania elementu o warto

Ğci 8 ? (2)

5. Rozwa

Īyü nastĊpujące drzewo binarne:

4

3

0

-1

2

1

a) Poda

ü kolejnoĞü odwiedzania wierzchoáków tego drzewa metodą preorder. (1)

b) Poda

ü kolejnoĞü odwiedzania wierzchoáków tego drzewa metodą postorder. (1)

c) Poda

ü kolejnoĞü odwiedzania wierzchoáków tego drzewa metodą inorder. (1)

6.

Poda

ü definicjĊ porządku czĊĞciowego. (2)

7.

Zak

áada siĊ, Īe tablica A=¢3,4,1,4² jest sortowana przez zliczanie wedáug

nast

Ċpującego algorytmu:

SORT-ZLICZANIE(A, B, k)

1

dla

i

m1 do k

2

wykonuj

C[i]

m 0

3

dla

j

m1 do length[A]

4

wykonuj

C[A[j]]

m C[A[j]] + 1

5

dla

i

m2 do k

6

wykonuj

C[i]

m C[i] + C[i-1]

7

dla

j

m length[A] w_dóá_do 1

8

wykonuj

{ B[C[A[j]]]

m A[j]

9

C[A[j]]

m C[A[j]] – 1 }

Przedstawi

ü, jak zmienia siĊ zawartoĞü tablic B i C po wykonaniu

kolejnych iteracji w wierszach 7-9. Przed wej

Ğciem do pĊtli w liniach 7-9

C=

¢1,1,2,4². (4)

Zestaw 3

1.

Zdefiniowa

ü jednym zdaniem nastĊpujące pojĊcia:

a)

rozmiar zadania; (1)

b)

notacja

f

; (1)

n

g

n

:

c)

operand typu *i w j

Ċzyku maszyny RAM; (1)

d) z

áoĪonoĞü pesymistyczna; (1)

e)

lista dwukierunkowa; (1)

f)

struktury z ograniczonym dost

Ċpem; (1)

g)

cykl w grafie nieskierowanym. (1)

- 108 -

background image

2.

Zapisa

ü w pseudojĊzyku algorytm wypisujący elementy listy L

reprezentowanej przy pomocy wska

Ĩników. (3)

3. Rozwa

Īyü program:

LOAD =10

STORE 2

Et1: READ 1
LOAD 1
JZERO Et3
LOAD 1
SUB 2
JGTZ Et2
JUMP Et1
Et2: LOAD 1
STORE 2
JUMP ET1
Et3: WRITE 2
HALT

a) Jaka jest warto

Ğü operandu w pierwszej komendzie LOAD? (1)

b) Jaka jest warto

Ğü operandu w komendzie z etykietą Et1? (1)

c) Jakiego typu adres wyst

Ċpuje w komendzie JZERO? (1)

d) (1) Poda

ü wynik dziaáania programu po wprowadzeniu liczb: 1 2 3 4 0.

e) (1) Poda

ü wynik dziaáania programu po wprowadzeniu liczb: 10 20 30 40 0.

4. Rozwa

Īyü graf nieskierowany G={V, E}, gdzie:

V={a, b, c, d},
E={(a,b), (a,c), (b,c), (b,d),(c,d)}.

a) Narysowa

ü ten graf. (1)

b) Naszkicowa

ü reprezentacjĊ grafu G z uĪyciem list sąsiedztwa. (2)

c) Naszkicowa

ü reprezentacjĊ grafu G z uĪyciem macierzy sąsiedztwa. (2)

5. Rozwa

Īyü wyraĪenie: (2-(1*(3+1))).

a) Poda

ü odwrotny zapis polski tego wyraĪenia. (1)

b) Przedstawi

ü ciąg operacji na stosie wykonywanych w trakcie otrzymywania

zapisu postfiksowego. (2)

c) Przedstawi

ü ciąg operacji na stosie wykonywanych w trakcie obliczania

warto

Ğci otrzymanego w p. b) wyraĪenia postfiksowego. (2)

6. Zak

áadamy Īe liczby: 1, 3, 6, –1, 0, 4, 2 są odpowiednio elementami

A[1],..., A[7] tablicy A.

a) Przedstawi

ü rysunki pokazujące ukáad tych liczb w tablicy A oraz w

w

Ċzáach odpowiedniego drzewa binarnego po zbudowaniu kopca. (2)

b) Jak b

Ċdzie wyglądaáa kolejka priorytetowa reprezentowana przez kopiec z

rys a) po wykonaniu operacji usuwania maksymalnego elementu? (2)

c) Rozmie

Ğciü liczby (pierwotnej) tablicy A w wĊzáach drzewa binarnego, tak,

aby powsta

áo drzewo BST o minimalnej gáĊbokoĞci. (1)

- 109 -

Zestaw 4

1.

Zdefiniowa

ü jednym zdaniem nastĊpujące pojĊcia:

a) g

áĊbokoĞü wierzchoáka drzewa; (1)

b) drzewo niezorientowane; (1)
c) operand typu i w j

Ċzyku maszyny RAM; (1)

d) silnie spójny graf skierowany; (1)
e) lista dwukierunkowa; (1)
f) sortowanie wewn

Ċtrzne; (1)

g) cykl w grafie skierowanym. (1)

2. Zapisa

ü w pseudojĊzyku procedurĊ MAX wyznaczającą maksymalną

spo

Ğród czytanych kolejno liczb. Procedura ta koĔczy pracĊ z chwilą

napotkania zera, wypisuj

ąc maksymalną liczbĊ. (3)

3.

Rozwa

Īyü program:

LOAD =10
STORE 2
Et1: READ 1
LOAD 1
JZERO Et3
LOAD 1
SUB 2
JGTZ Et2
JUMP Et1
Et2: LOAD 1
STORE 2
JUMP ET1
Et3: WRITE 2
HALT

a) Jaka jest warto

Ğü operandu w pierwszej komendzie LOAD? (1)

b) Jaka jest warto

Ğü operandu w komendzie z etykietą Et1? (1)

c) Jakiego typu adres wyst

Ċpuje w komendzie JZERO? (1)

d) (1) Poda

ü wynik dziaáania programu po wprowadzeniu liczb: 1 2 3 4 0.

e) (1) Poda

ü wynik dziaáania programu po wprowadzeniu liczb: 10 20 30 40 0.

4.

Rozwa

Īyü graf skierowany G={V, E}, gdzie:

V={a, b, c, d},
E={(a,b), (a,c), (b,d), (c,b),(d,c), (d,d)}.

a) Narysowa

ü ten graf. (1)

b) Naszkicowa

ü reprezentacjĊ grafu G z uĪyciem list sąsiedztwa. (2)

c) Naszkicowa

ü reprezentacjĊ grafu G z uĪyciem macierzy sąsiedztwa. (2)

5.

Rozwa

Īyü wyraĪenie: (((2-1)*3)+1).

a) Poda

ü odwrotny zapis polski tego wyraĪenia. (1)

b) Przedstawi

ü ciąg operacji na stosie wykonywanych w trakcie otrzymywania

zapisu postfiksowego. (2)

- 110 -

background image

c) Przedstawi

ü ciąg operacji na stosie wykonywanych w trakcie obliczania

warto

Ğci otrzymanego w p. b) wyraĪenia postfiksowego. (2)

6. Rozwa

Īyü nastĊpujące drzewo binarne:

4

3

0

-1

2

1

a) Poda

ü kolejnoĞü odwiedzania wierzchoáków tego drzewa metodą preorder. (1)

b) Poda

ü kolejnoĞü odwiedzania wierzchoáków tego drzewa metodą postorder. (1)

c) Poda

ü kolejnoĞü odwiedzania wierzchoáków tego drzewa metodą inorder. (1)

d) Czy drzewo to ma w

áasnoĞü drzewa BST? (1)

e) Czy drzewo to ma w

áasnooĞü kopca? (1)

Zestaw 5

1.

Zdefiniowa

ü jednym zdaniem nastĊpujące pojĊcia:

a) rozmiar zadania; (1)
b) równomierne kryterium wagowe; (1)
c) operand typu i w j

Ċzyku maszyny RAM; (1)

d) spójny graf nieskierowany; (1)
e) procedura rekurencyjna. (1)

2.

Zapisa

ü w pseudojĊzyku procedurĊ, która wypisuje minimalny element

tablicy jednowymiarowej A zadanej jako parametr. (3)

3.

Rozwa

Īyü program:

LOAD =0
STORE 1
LOAD =1
STORE 2
ET1: LOAD =5
SUB 2
JGTZ Et2
JUMP Et3
Et2: LOAD 1
ADD 2
STORE 1
LOAD 2
ADD =1
STORE 2
JUMP ET1
Et3: WRITE 1
HALT

a) Jaka jest waga logarytmiczna operandu w pierwszej komendzie STORE? (1)

- 111 -

- 112 -

b) Jaka jest warto

Ğü operandu w komendzie z etykietą Et1? (1)

c) Jakiego typu adres wyst

Ċpuje w komendzie JGTZ? (1)

d) Ile razy wykona si

Ċ komenda ADD 2 ? (1)

e) Poda

ü wynik dziaáania programu. (1)

f) Ile rejestrów wykorzystano w obliczeniach? (1)
g) Jakie zadanie pe

áni tutaj rejestr 0 ? (1)

4. Zdefiniowa

ü jednym zdaniem nastĊpujące pojĊcia:

a) regularne drzewo binarne; (1)
b) podstawowa w

áasnoĞü kopca; (1)

c) w

Ċzeá wewnĊtrzny drzewa; (1)

d) drzewo poszukiwa

Ĕ binarnych; (1)

e) asymptotycznie optymalny algorytm sortuj

ący wyáącznie za pomocą

porówna

Ĕ. (1)

5. Napisa

ü iteracyjną wersjĊ algorytmu poszukiwania w drzewie BST

elementu o podanym kluczu. (3)

6. Poda

ü istotĊ metody „dziel i zwyciĊĪaj”. (2)

7. Zak

áadamy Īe liczby: 1, 2, 3, 4, 5, 6 są odpowiednio elementami A[1],...,

A[6] tablicy A.

a) Sporz

ądziü rysunki pokazujące rozmieszczenie tych liczb w tablicy A oraz

w w

Ċzáach odpowiedniego drzewa binarnego tak, aby byá to stan wyjĞciowy

dla procedury budowania kopca. (1)

b) Przedstawi

ü rysunki podobne jak w p. a), ale po zbudowaniu kopca. (2)

c) Jak b

Ċdzie wyglądaáa kolejka priorytetowa reprezentowana przez kopiec z

rys. b) po wykonaniu operacji usuwania maksymalnego elementu? (2)


Wyszukiwarka

Podobne podstrony:
ćw nr 7 algorytm z książki
ćw nr 7 algorytm z książki
Historia książki 4
Układy Napędowe oraz algorytmy sterowania w bioprotezach
5 Algorytmy
5 Algorytmy wyznaczania dyskretnej transformaty Fouriera (CPS)
Historia książki
Tętniak aorty brzusznej algorytm
Algorytmy rastrowe
Algorytmy genetyczne
Teorie algorytmow genetycznych prezentacja
Algorytmy tekstowe
Algorytmy i struktury danych Wykład 1 Reprezentacja informacji w komputerze
ALGORYTM EUKLIDESA

więcej podobnych podstron