ASD komplet


A.Szewczyk (Kat.Informatyki AGH)

Przedm.“ASD”, 1999/2000, sem.letni

2000-02

1.Wstęp do przedmiotu

1.1.Nazwa przedmiotu

Nazwa polska: „Algorytmy i struktury danych”

Nazwa angielska: „Data algorithms and structures”

albo: „Data structures and algorithms”

Semantyka: „Struktury i algorytmy dotyczące danych”

Pierszeństwo struktur przed algorytmami

1.2.Pojęcie informacji

(ujęcie obiektowe)

0x01 graphic

1.3.Dane proste i złożone

Dane: zapisy informacji na nośniku komputerowym

Dana prosta: gdy część zapisu nie jest zapisem informacji

Dana złożona:

1) podłoże danej

2) pokrycie podłoża

3) wyróżnienia działek podłoża

1.4.Podłoże danej złożonej

1) działki („pozycje”) podłoża (zbiór P)

2) powiązania między działkami (zbiory R1, R2, ... relacji RiP × P)

1.5.Klasyfikacja danych złożonych

(według struktury podłoża)

Struktury:

mnogościowe

liniowe

pierścieniowe

drzewiaste

sieciowe (grafowe)

1.6.Pokrycie podłoża

Zbiór C danych składowych

Funkcja pokrywająca γ : P C

Struktury wielowarstwowe

1.7.Ograniczenia pokrycia

Ograniczenia ilościowe równościowe i nierównościowe

Ograniczenia co do typu

Jednorodność pokrycia

1.8.Wyróżnienia działek podłoża

(W1, W2, ... ⊆ P)

1.9.Struktury dynamiczne

( = struktury zanurzone w czasie)

Stan struktury dynamicznej

Zdarzenia i procesy

Rozkład procesu na podprocesy

Powiązania między procesami

Operacje proste i złożone

Operacje na wyróżnieniach, na pokryciu i na podłożu

1.10.Plan przedmiotu

Rozdz.1: Wstęp do przedmiotu

Rozdz.2: Struktury mnogościowe

Rozdz.3 - 10: Struktury liniowe (w tym sieci odsyłaczowe i tablice rozproszone)

Rozdz.11: Struktury pierścieniowe

Rozdz.12 - 15: Wprowadzenie do struktur grafowych i struktury drzewiaste

Rozdz.16: Struktury grafowe

Rozdz.17: Dane w pamięci niejednorodnej

Rozdz.18: Kompresja danych

1.11.Zawartość treściowa poszczególnych rozdziałów

Struktura statyczna

Dynamika (operacje proste i złożone; algorytmy operacji złożonych)

Problematyka implementacyjna

Zastosowania

1.12.Literatura w języku polskim

(kolejność chronologiczna odwrócona)

Banachowski L., Diks K., Rytter W.: Algorytmy i struktury danych. WNT, Warszawa, 1996 (podejście nieco odmienne od mojego, zalecam jednak zapoznanie się z tą książką)

Banachowski L., Kreczmar A., Rytter W.: Analiza algorytmów i struktur danych. Warszawa, 1987 (książka przydatna fragmentami)

Reingold E.M., Nievergelt J., Deo N.: Algorytmy kombinatoryczne. PWN, Warszawa, 1985 (nieco odmienny zapis operacji złożonych; bardzo dobre odsyłacze do literatury źródłowej)

Aho A.V., Hopcroft J.E., Ullman J.D.: Projektowanie i analiza algorytmów komputerowych. PWN, Warszawa, 1983 (książka przydatna fragmentami)

Jagielski R.: Tablice rozproszone. WNT, Warszawa, 1982 (bardzo dobre opracowanie, ograniczone jednak do problematyki tablic rozproszonych)

Lipski W.: Kombinatoryka dla programistów. Warszawa, 1982 (książka przydatna w zakresie algorytmów grafowych)

Dembiński P., Małuszyński J.: Matematyczne metody definiowania języków programowania. Warszawa, 1981 (przydatne rozdziały: algebra wielorodzajowa; abstrakcyje typy danych)

Deo N.: Teoria grafów i jej zastosowania w technice i informatyce. Warszawa, 1980 (kompletne opraco-wanie teorii grafów)

Wirth N.: Algorytmy + struktury danych = programy. WNT, Warszawa, 1980 (książka bardzo dobra od strony dydaktycznej, nie obejmuje jednak całego materiału)

Turski M.W.: Struktury danych. WNT, Warszawa, 1971 (pierwsza polska książka ze struktur danych, ukazały się dwa wydania)

1.13.Literatura w języku angielskim

(kolejność chronologiczna odwrócona)

Decker R.: Data Structures. Prentice Hall, Englewood Clffs, 1989 (dostępna w Bibliotece Głównej AGH; omawia m.in. abstrakcyjne typy danych)

Aho A.V., Hopcroft J.E., Ullman J.D.: Data Structures and Algorithms. Addison-Wesley, Reading (MA), 1985 (bardzo dobrzy autorzy, książka raczej trudno dostępna)

Horowitz E., Sahni S.: Fundamentals of Data Structures. Pitman, London, 1977 (książka bardzo dobra od strony dydaktycznej)

Hall P.A.V.: Computational Structures. An Introduction to Non-numerical Computing. London 1975 (interesujące podejście do budowy edytorów tekstowych; istnieje wersja rosyjska)

Lorin H.: Sorting and Sort Systems (1975) (klasyczna monografia metod sortowania; istnieje wersja rosyjska)

Knuth D.: The Art of Computer Programming. Vol.3: Sorting and Searching (1973)

Knuth D.: The Art of Computer Programming. Vol.1: Fundamental Algorithms (1968) (obydwa tomy monografii Knutha zawierają ilościowe wzory dla niektórych algorytmów)

1.14. Pozycja przedmiotu w planie studiów

Przedmioty poprzedzające:

Wstęp do informatyki

Przedmioty poprzedzane (m.in.):

Bazy danych

Systemy informatyczne

Metody obliczeniowe

Sztuczna inteligencja

========

2.Struktury mnogościowe

2.1.Zbiory

2.1.1.Definicja

Struktura mnogościowa dynamiczna

o pokryciu zupełnym różnowartościowym

Termin „element zbioru”

2.1.2.Operacje proste

Sprawdzanie czy zbiór jest niepusty

Dołączanie elementu

Wybór elementu

Usuwanie elementu

2.1.2.Operacje złożone

Sumowanie zbiorów

Iloczyn zbiorów

Różnica zbiorów

Symetryczna różnica zbiorów

2.2.Multizbiory

2.2.1.Definicja

Struktura mnogościowa dynamiczna

o pokryciu zupełnym niekoniecznie różnowartościowym

2.2.2.Operacje proste i złożone

Analogiczne jak dla zbiorów

2.3.Rekordy

2.3.1.Definicja

Struktura mnogościowa dynamiczna:

o podłożu stałym

o dostępie adresowym

2.3.2.Adresacja działek

Zbiór adresów A (adres = "nazwa pola")

Funkcja adresująca α : A P

2.3.3.Operacje proste

Odczytywanie zawartości działki ( działka = "pole")

Zmiana zawartości działki

2.3.4.Termin „plik”

Terminem tym określana będzie każda struktura o działkach pokrytych przez rekordy

========

3.Struktury liniowe: wprowadzenie

3.1.Podłoże liniowe

Działki początkowa i końcowa

Relacja następstwa i relacja poprzedzania

Relacje osiągalności naprzód i wstecz

Podłoże liniowe puste

Struktura liniowa dynamiczna

3.2.Tablica liniowa

3.2.1.Definicja

Struktura dynamiczna

o podłożu liniowym stałym

o pokryciu jednorodnym

o dostępie adresowym

3.2.2.Pokrycie częściowe

Rozmieszczenie działek niepustych: zwarte lub luźne

3.2.3.Tablica liniowa numerowana (tablica TLN)

Numeracja działek podłoża:

gdy zbiór adresów A jest przedziałem liczb całkowitych

3.2.4.Operacje proste

Odczytywanie zawartości działki

Zmiana zawartości działki

3.2.5.Rozmieszczenie elementów tablicy

Rozmieszczenie zwarte

Rozmieszczenie luźne

Rozmieszczenie przypadkowe

Rozmieszczenie sterowane zawartością działki:

monotoniczne

algorytmiczne

3.2.6.Monotoniczność tablicy

Warunek: porządek liniowy w zbiorze danych pokrywających C

oznaczenie: c1 c2 ( = „c1 jest wcześniejsze od c2)

Monotoniczność zwykła (niemalejąca):

jeżeli dla każdej pary adresów a1 < a2

pokrycia c1 i c2 działek p1 = α (a1) i p2 = α (a2)

spełniają warunek c1 = c2 albo c1 c2

Monotoniczność odwrócona (nierosnąca):

Jw., tylko z a1 < a2 wynika c1 = c2 albo c2 c1

3.2.7.Operacje złożone

Rozmieszczanie elementów

Odszukiwanie działki lub działek o zadanym pokryciu:

sekwencyjne; binarne; interpolacyjne; algorytmiczne

Reorganizacja tablicy:

monotonizacja („sortowanie”)

zmiana algorytmu rozmieszczającego

3.3.Plik TLN (tablicowy liniowy numerowany)

3.3.1.Definicja

Tablica TLN

o działkach pokrytych przez rekordy

jednakowego typu

3.3.2.Pole kluczowe rekordu

Zastosowanie:

do rozmieszczania rekordów

do odszukiwania rekordów

do sortowania pliku

3.3.3.Rozmieszczanie rekordów

Rozmieszczanie; zwarte; luźne; przypadkowe; sterowane zawartością rekordu:

monotoniczne; algorytmiczne

3.3.4.Odszukiwanie rekordów

Odszukiwanie sekwencyjne; binarne; algorytmiczne

Zakres stosowalności i ocena czasu

odszukiwania sekwencyjnego i binarnego

3.3.5.Reorganizacja pliku tablicowego

Monotonizacja („sortowanie”)

Zmiana algorytmu rozmieszczającego

3.4.Wstęp do algorytmów sortujących

3.4.1.Rząd złożonościowy algorytmu

Założenie:

funkcje rzeczywiste dodatnie f i g

argumentu naturalnego n

(np. długość pliku n i czas sortowania f(n))

Zapis f(n) O(g(n)) (czytamy: funkcja f jest rzędu funkcji g,

O” od słowa „ordo” lub „order” = rząd) oznacza,

że istnieją współczynniki rzeczywiste dodatnie c1 i c2

oraz liczba naturalna N takie, że dla kazdego n > N jest

c1g(n) f(n) c2g(n)

3.4.2.Twierdzenia o rzędzie złożonościowym

1) Zwrotność: f(n) O(f(n))

2) Symetria: Jezeli f(n) O(g(n)) to g(n) O(f(n))

3) Przechodniość: Jezeli f(n) O(g(n)) oraz g(n) O(h(n)),

to f(n) O(h(n))

4) Twierdzenie o mnożeniu przez współczynnik:

Jeżeli f(n) jest rzędu g(n), a k jest współczynnikiem rzeczywistym dodatnim,

to kf(n) jest też rzędu g(n).

5) Twierdzenie o sumie: Funkcja f + g jest rzedu max (f, g)

6) Twierdzenie o iloczynie: Jezeli f1 jest rzedu g1, a f2 jest rzedu g2,

to f1 f2 jest rzędu g1 g2

7) Wnioski z twierdzeń (4), (5) i (6):

a) Wielomian a1nm + a2nm-1 + ... jest rzedu nm

b) O( lgk n) = O( lgl n) także dla kl, zamiast O( lgk n) czy O( lgl n)

można więc pisać O( lg n)

3.4.3.Najczęściej występujące rzędy złożonościowe

Stały: O(1); liniowy: O(n); kwadratowy: O(n2); potęgowy: O(nm); wykładniczy: O(e n); logarytmiczny: O( lg n); liniowo - logarytmiczny: O( n lg n)

3.4.4.Klasyfikacja algorytmów sortujących

1) Według rodzaju struktury sortowanej

np. tablica; lista; łańcuch odsyłaczowy

2) Według metody sortowania

metody bezpośrednie:

przestawianie rekordów realizowane natychmiast

metody pośrednie:

etap logiczny - zapis informacji o potrzebnych przestawieniach

etap fizyczny - realizacja przestawień

3) Według miejsca sortowania

sortowanie wewnętrzne: w pamięci operacyjnej

sortowanie zewnętrzne: z wykorzystaniem pamięci masowej

4) Według zużycia pamięci pomocniczej

intensywne („in situ”): z małym zapotrzebowaniem na pamięć pomocniczą

ekstensywne: z dużym zapotrzebowaniem

5) Według stabilności

stabilne: bez przestawiania rekordów o jednakowych kluczach

niestabilne: z możliwością przestawiania rekordów o jednakowych kluczach

6) Według wydajności (podział umowny)

metody proste (złożoność kwadratowa lub gorsza)

metody szybkie (złożoność liniowo-logarytmiczna lub lepsza)

7) Według ilości kluczy w rekordzie

z jednym kluczem sortowania

z wieloma kluczami równorzędnymi

z wieloma kluczami zhierarchizowanymi

========

4.Sortowanie tablic: metody proste

4.1.Metoda pęcherzykowa

(„bąbelkowa”; ang. bubblesort)

4.1.1.Ogólna charakterystyka metody

Mała przydatność praktyczna

Podstawa metod Shella

Podstawa metody grzebieniowej

4.1.2.Pęcherzykowa kontrola monotoniczności

Inwersje elementarne i ich kontrola

4.1.3.Podstawowy wariant metody

Sekwencyjne usuwanie inwersji elementarnych

Efekt jednokrotnego przeglądu sekwencyjnego

Podstawowy algorytm pęcherzykowy

Rząd złożonościowy O(n2) z dużym współczynnikiem

4.1.3.Wariant ze zmienną logiczną

Podstawienia bool := false i bool := true

Warunek wyjścia z pętli

Ogólna ocena wariantu

4.1.4.Wariant wahadłowy ze zderzakami

Organizacja pętli zewnętrznej

Warunek wyjścia z pętli

Ogólna ocena wariantu

4.2.Metoda wstawiania

(ang. insertion sort)

4.2.1.Podstawowa koncepcja metody

Część monotoniczna pliku:

pusta

jednoelementowa

seria naturalna

Poszukiwanie miejsca dla nowego rekordu:

sekwencyjne („metoda wstawiania prostego”)

binarne („metoda wstawiania połówkowego”)

warunek stabilności

Wstawianie z przesuwaniem

Poszukiwanie sekwencyjne z jednoczesnym przesuwaniem

4.2.2.Ogólna charakterystyka metody

Rząd złożonościowy O(n2)

Zalecana dla n ≤ 20

4.3.Metoda wyboru

(„metoda prostego wyboru”; „metoda selekcji”; ang. selection sort)

4.3.1.Podstawowa koncepcja metody

Część monotoniczna pliku: pusta

Poszukiwanie minimum

Warunek stabilności

Wariant podstawowy: przestawianie

Wariant stabilny: wstawianie z przesuwaniem

4.3.2.Ogólna charakterystyka metody

Rząd złożonościowy dla poszukiwania minimum: O(n2)

Rząd złożonościowy dla przestawiania: O(n)

Rząd złożonościowy dla przesuwania: O(n2)

Rząd złożonościowy ogólny: O(n2)

Wariant podstawowy zalecany dla n ≤ 50

========

5.Sortowanie tablic: metody szybkie

5.1.Metoda podziałów

(„Quicksort”, autor C.A.R.Hoare, r.1962)

5.1.1.Ogólna charakterystyka metody

Metoda liniowo-logarytmiczna (jedna z najszybszych)

Niebezpieczeństwo „ukwadratowienia”

Brak stabilności

5.1.2.Wariant podstawowy (Wirtha)

1: procedure qs(id, ig);

2: begin i := id; j := ig;

3: kp := k[(id + ig) div 2];

4: repeat

5: while k[i] < kp do i := i + 1; while k[j] > kp do j := j − 1;

6: if ij then begin R[i] :=: R[j]; i := i + 1; j := j − 1 end

7: until i > j;

8: if j > id then qs(id, j); if i < ig then qs(i, ig)

9: end {qs}

Złożoność przy podziałach korzystnych: O(n log n)

Złożoność przy podziałach niekorzystnych: O(n2)

Złożoność statystyczna

5.1.3.Wariant Horowitza

Klucz kp z początku tablicy

Dla pliku monotonicznego złożoność kwadratowa

5.1.4.Wariant losowy

Nakład obliczeń na losowanie

5.1.5.Wariant z medianą z trzech

Nakład na obliczanie mediany

5.1.6.Wariant iteracyjny

Kolejność sortowania po podziale

5.1.7.Kombinacja z metodą prostą

Np. z metodą wstawiania

5.1.8.Algorytm poszukiwania mediany

Ok. dwa razy szybszy od wariantu podstawowego

5.1.9.Algorytm "Quickersort"

Podział na trzy części

5.2.Metoda scalania

(„metoda łączenia”, ang. mergesort)

5.2.1.Ogólna charakterystyka metody

Ekstensywność metody

Rząd złożonościowy O(n log n)

Metoda charakterystyczna dla list i łańcuchów

oraz dla sortowania zewnętrznego

5.2.2.Scalanie plików monotonicznych

Scalanie dwustrumieniowe

Scalanie wielostrumieniowe

5.2.3.Podstawowy (iteracyjny) wariant metody

Pamięć pomocnicza

Podział na pary elementarne

Algorytm podstawowy

Złożoność algorytmu podstawowego

Rozmieszczenie odcinków resztkowych

5.2.4.Wariant rekurencyjny

Zapis algorytmu rekurencyjnego

Rozmieszczenie odcinków resztkowych

5.2.5.Wariant naturalny

Serie naturalne

Granice między seriami

Efektywność wariantu naturalnego

5.3.Metoda grzebieniowa

(Combsort)

5.3.1.Uwagi wstępne

Opublikowana: „Byte”, kwiecień 1991

Autorzy: S.Lacey (specjalność: medycyna, genetyka);

R.Box (specjalność: geofizyka; matematyka)

Jest rozwinięciem metody pęcherzykowej

5.3.2.Wariant podstawowy

Tablica sortowana: A: array[1..size]

1: begin gap := size;

2: repeat

3: gap := max(trunc(gap/1.3), 1); top := size gap;

4: swapped := false;

5: for i := 1 to top do begin j := i + gap;

6: if k[i] > k[j] then begin A[i] :=: A[j]; swapped := true end {if}

7: end {for}

8: until (gap = 1) and not swapped

9: end {cs}

5.3.3.Wariant "Combsort 11"

1: begin gap := size;

2: repeat

3: gap := trunc(gap/1.3);

4: case gap of 0: gap := 1; 9, 10: gap := 11 end {case};

5: top := size gap; swapped := false;

6: for i := 1 to top do begin j := i + gap;

7: if k[i] > k[j] then begin A[i] :=: A[j]; swapped := true end {if}

8: end {for}

9: until (gap = 1) and not swapped

10: end {cs11}

5.3.4.Ogólna charakterystyka sortowania grzebieniowego

Rząd złożonościowy O(n log n)

Złożoność statystyczna: ok. 1,9 qs

Prosty algorytm

========

6.Sieci odsyłaczowe

6.1.Wprowadzenie

6.1.1.Podstawa sieci

Przypadek najczęstszy: plik TLN

Przypadek ogólny: dowolny plik o dostępie adresowym

Pole odsyłaczowe i odsyłacz („wskaźnik”; ang. pointer)

Odsyłacz niewłaściwy („nil”)

Kadłub rekordu ( = rekord bez pól odsyłaczowych)

Trzon rekordu ( = rekord bez pól odsyłaczowych i kluczowych)

6.1.2.Powiązania odsyłaczowe

Relacja następstwa odsyłaczowego

Relacja osiągalności odsyłaczowej

Odsyłacze zewnętrzne

6.1.4. Sieć odsyłaczowa nieswobodna

(B, I, D, R) gdzie:

B - podstawa sieci

I - zbiór odsyłaczy zewnętrznych początkowych

D - zbiór odsyłaczy zewnętrznych wyróżniających

R - zbiór rekordów osiągalnych z I

6.1.5. Sieć odsyłaczowa swobodna

Sieci nieswobodne równoważne

Klasa równoważnościowa sieci nieswobodnych

6.1.4.Operacje proste

Odczytanie zawartości rekordu wyróżnionego

Zmiana zawartości rekordu wyróżnionego

Zmiana wartości odsyłacza zewnętrznego

6.2.Proste przypadki sieci odsyłaczowych

6.2.1.Łańcuch odsyłaczowy jednokierunkowy

0x01 graphic

6.2.2.Łańcuch odsyłaczowy dwukierunkowy

0x01 graphic

6.2.3.Pierścień odsyłaczowy jednokierunkowy

0x01 graphic

6.2.4. Pierścień odsyłaczowy dwukierunkowy

0x01 graphic

7.Sortowanie tablic: metody pośrednie

7.1.Sortowanie łańcuchowe

7.1.1.Etap logiczny

1) Powiązać rekordy w łańcuch odsyłaczowy w kolejności fizycznej.

2) Posortować łańcuch dowolną metodą.

7.1.2.Etap fizyczny - wariant ekstensywny

Czytając rekordy w kolejności łańcucha odsyłaczowego („logicznej”) przepisywać je do tablicy pomocniczej. Działki tablicy pomocniczej zapełniać w kolejności fizycznej.

7.1.3.Etap fizyczny - wariant z łańcuchem dwukierunkowym

1) Uzupełnić łańcuch do dwukierunkowego

2) Czytając rekordy w kolejności logicznej, przenosić je do działek tej samej tablicy. Działki tablicy zapełniać w kolejności fizycznej. Rekordy przeszkadzające wypychać na zwalniające się miejsca, odpowiednio korygując skierowane do nich odsyłacze w rekordach logicznie sąsiednich.

7.1.4.Etap fizyczny - wariant McLarena

Czytając rekordy w kolejności logicznej, przenosić je do działek tej samej tablicy. Działki tablicy zapełniać w kolejności fizycznej. Rekordy przeszkadzające wypychać na zwalniające się miejsca. Nowy adres rekordu wypchniętego wpisać do pola odsyłaczowego rekordu wypychającego.

7.2.Sortowanie skorowidzowe

7.2.1.Etap logiczny

1) Utworzyć skorowidz. Zapełnić skorowidz adresami działek tablicy głównej w ich kolejności fizycznej.

2) Posortować zawartość skorowidza dowolną metodą w oparciu o klucze, zawarte we wskazywanych rekordach tablicy głównej.

7.2.2.Etap fizyczny („cykliczne wciąganie”)

1) Usunnąć rekord z pierwszej działki do pomocniczego magazynu.

2) Cyklicznie wciągać rekordy wskazywane przez zawartości działek skorowidza do opróżniających się działek tablicy głównej. Rekord ulokowany definitywnie („trwały”) zaznaczać wstawiając do odpowiedniej działki skorowidza jej własny adres.

3) Po ukończeniu cyklu wciągań przeglądać sekwencyjnie skorowidz od miejsca zakończenia cyklu poprzedniego. Nowy cykl rozpoczynać od pierwszego napotkanego rekordu nietrwałego.

4) Realizację algorytmu zakończyć po dojściu do końca tablicy.

7.2.3.Skorowidz rozszerzony

Działka skorowidza oprócz odsyłacza zawiera klucz wskazywanego rekordu.

7.3.Sortowanie licznikowe

7.3.1.Założenie wstępne

Numeracja działek tablicy od 0 do n - 1.

7.3.2.Etap logiczny

1) Utworzyć pomocniczą tablicę liczników.

2) Sekwencyjnie przeglądać tablicę główną, traktując klucz w aktualnie rozpatrywanym rekordzie za wzorcowy.

3) Dla każdego klucza wzorcowego zliczyć rekordy o kluczach mniejszych. Wynik umieścić w odpowiednim liczniku.

4) W przypadku kluczy nieróżnowartościowych usunąć powtórzenia wartości liczników, odpowiednio je inkrementując. Po tej operacji zawartość k - tego licznika jest docelowym adresem rekordu z działki nr k.

7.3.3.Etap fizyczny („cykliczne wypychanie”)

1) Rozpoczynając od działki początkowej przenosić rekordy na ich definitywne lokalizacje według aktualnych wartości odpowiednich liczników. Rekordy przeszkadzające wypychać na ich lokalizacje według tej samej zasady. Rekordy trwałe zaznaczać, wstawiając do odpowiedniego licznika jego własny adres.

2) Po ukończeniu cyklu wypychań poszukiwać sekwencyjnie początku nowego cyklu od miejsca zakończenia cyklu poprzedniego. Nowy cykl rozpoczynać od pierwszego napotkanego rekordu nietrwałego.

3) Realizację algorytmu zakończyć po dojściu do końca tablicy.

7.3.4.Ogólna ocena metody

Metoda mało wydajna, jej analiza może być traktowana jako ćwiczenie.

========

8.Struktury liniowe o podłożu zmiennym

8.1.Stos

(ang. stack)

8.1.1.Definicja

Struktura dynamiczna:

o podłożu liniowym zmiennym,

o pokryciu zupełnym jednorodnym,

o dynamice stosowej.

8.1.2.Wyróżnienia

Wierzchołek stosu

Dno stosu

8.1.3.Szczególne przypadki

Stos elementarny

Stos pusty

8.1.4.Operacje proste

Sprawdzanie niepustości stosu

Opróżnianie stosu

Wprowadzanie nowego elementu na wierzchołek

Odczyt zawartości wierzchołka

Usuwanie (kasowanie, „strącanie”) wierzchołka

8.1.6.Operacje złożone

Przeglądanie stosu

8.1.7.Implementacje tablicowe

Stos o ograniczonej wysokości na tablicy liniowej

Dwa stosy na tablicy

Wiele stosów na tablicy

8.1.8.Implementacja odsyłaczowa

Łańcuch jednokierunkowy

8.1.9.Zastosowania

Magazyn LIFO („Last In First Out”)

Prosty magazyn jednorodnych elementów

8.2.Kolejka

(ang. queue)

8.2.1.Definicja

Jak stos, lecz z dynamiką kolejkową

8.2.2.Wyróżnienia

Początek kolejki

Koniec kolejki

8.2.3.Przypadki szczególne

Kolejka elementarna

Kolejka pusta

8.2.4.Operacje proste

Sprawdzanie niepustości kolejki

Opróżnianie kolejki

Wprowadzanie nowego elementu na koniec kolejki

Odczytywanie zawartości działki początkowej

Usuwanie (kasowanie) elementu początkowego

8.2.5.Operacje złożone

Przeglądanie kolejki

Konkatenacja kolejek

8.2.6.Implementacje tablicowe

Kolejka o ograniczonej długości na tablicy liniowej

Pełzanie kolejki i implementacja cykliczna

Wiele kolejek na tablicy

8.2.7.Implementacje odsyłaczowe

Łańcuch jednokierunkowy

Pierścień jednokierunkowy

8.2.8.Zastosowania

Magazyn FIFO („First In First Out”)

8.3.Talia niesymetryczna

(także „półka”; ang. deque)

8.3.1.Definicja

Jak stos, lecz z dynamiką talii niesymetrycznej

8.3.2.Wyróżnienia

Krańce lewy i prawy

8.3.3.Przypadki szczególne

Talia elementarna

Talia pusta

8.3.4.Operacje proste

Sprawdzanie niepustości talii

Opróżnianie talii

Wprowadzanie nowego elementu na lewy kraniec talii

Wprowadzanie nowego elementu na prawy kraniec talii

Odczytywanie zawartości działki krańcowej lewej

Kasowanie działki krańcowej lewej

8.3.5.Operacje złożone

Jak dla kolejki

8.3.6.Implementacje tablicowe

Jak dla kolejki

8.3.7.Implementacje odsyłaczowe

Jak dla kolejki

8.3.8.Zastosowanie

Kolejka zadań z pierszeństwem wysokim i zwykłym

8.4.Talia symetryczna

8.4.1.Definicja

Jak talia niesymetryczna, lecz z dynamiką talii symetrycznej

8.4.2.Wyróżnienia

Jak dla talii niesymetrycznej

8.4.3.Przypadki szczególne

Jak dla talii niesymetrycznej

8.4.4.Operacje proste

Jak dla talii niesymetrycznej, a oprócz tego:

Odczytywanie zawartości działki krańcowej prawej

Kasowanie działki krańcowej prawej

8.4.5.Operacje złożone

Jak dla talii niesymetrycznej

8.4.6.Implementacje tablicowe

Jak dla talii niesymetrycznej

8.4.7.Implementacje odsyłaczowe

Łańcuch dwukierunkowy

8.4.8.Zastosowanie

Kolejka zadań dla dwóch wykonawców z ich wzajemnym zastępowaniem się.

8.5.Lista jednokierunkowa

(niesymetryczna)

8.5.1.Definicja

Jak stos, lecz z dynamiką listy jednokierunkowej

8.5.2.Wyróżnienia

Działka początkowa

Działka robocza

8.5.3.Przypadki szczególne

Lista elementarna

Lista pusta

8.5.4.Operacje proste

Sprawdzanie niepustości listy

Opróżnianie listy

Przesuwanie wyróżnienia roboczego na działkę początkową

Przesuwanie wyróżnienia roboczego na działkę następną

Wprowadzanie nowego elementu na początek listy

Wprowadzanie nowego elementu na prawo od działki wyróżnionej roboczo

Odczytywanie zawartości działki wyróżnionej roboczo

Kasowanie działki początkowej

Kasowanie działki położonej na prawo od działki wyróżnionej roboczo

8.5.5.Operacje złożone

Przeglądanie listy

Przeszukiwanie listy

Sortowanie listy

Konkatenacja list

8.5.6.Implementacje tablicowe

Implementacje zwarta i luźna

8.5.7.Implementacja odsyłaczowa

Łańcuch jednokierunkowy

8.5.8.Zastosowania

Plik listowy

Implementacja zbioru lub multizbioru

8.6.Lista dwukierunkowa

(symetryczna)

8.6.1.Definicja

Jak lista jednokierunkowa, lecz z dynamiką listy dwukierunkowej

8.6.2.Wyróżnienia

Działka początkowa

Działka końcowa

Działka robocza

8.6.3.Przypadki szczególne

Jak dla listy jednokierunkowej

8.6.4.Operacje proste

Jak dla listy jednokierunkowej, a oprócz tego:

Przesuwanie wyróżnienia roboczego na działkę końcową

Przesuwanie wyróżnienia roboczego na działkę poprzednią

Wprowadzanie nowego elementu na koniec listy

Wprowadzanie nowego elementu na lewo od działki wyróżnionej roboczo

Kasowanie działki końcowej

Kasowanie działki położonej na lewo od działki wyróżnionej roboczo

8.6.5.Operacje złożone

Jak dla listy jednokierunkowej, lecz z możliwością stosowania bardziej dogodnych algorytmów.

8.6.6.Implementacje tablicowe

Jak dla listy jednokierunkowej

8.6.7.Implementacje odsyłaczowe

Łańcuch dwukierunkowy

8.6.8.Zastosowania

Jak dla listy jednokierunkowej, lecz z możliwością stosowania bardziej dogodnych algorytmów.

9.Sortowanie wielokluczowe i rozrzutowe

9.1.Przypadek kluczy równorzędnych

Przypadek kluczy równorzędnych omówiony był w rozdziale dotyczącym pośrednich metod sortowania.

9.2.Klucze zhierarchizowane

9.2.1.Przykłady

1) Klucz tekstowy w rozbiciu na klucze częściowe znakowe

2) Klucz numeryczny w rozbiciu na cyfry dziesiętne, dwójkowe lub w dowolnym innym zapisie pozycyjnym

9.2.2.Sortowanie pozycyjne, strategia MSD

(„Most Significant Digit First”)

1) Sortuj według kolejnych kluczy częściowych zaczynając od najstarszego

2) Sortowanie według następnego klucza: osobno dla każdej strefy równych wartości klu-cza bezpośrednio starszego

9.2.3.Sortowanie pozycyjne, strategia LSD

(„Least Significant Digit First”)

1) Sortuj według kolejnych kluczy częściowych zaczynając od najmłodszego

2) Sortowanie według następnego klucza: jednokrotne dla całego pliku

3) Każde sortowanie częściowe oprócz pierwszego: obowiązuje metoda stabilna

9.3.Sortowanie rozrzutowe

(ang. bin sort lub bucket sort, sortowanie „wiaderkowe”)

9.3.1.Ogólna charakterystyka metody

Metoda w zasadzie silnie ekstensywna, nadaje się tylko w przypadku małego zbioru dopuszczalnych wartości klucza sortowania. Ponieważ jest stabilna, może być stosowana jako metoda sortowania częściowego w ramach sortowania pozycyjnego.

9.3.2.Wariant podstawowy

1) W przypadku klucza sortowania o m wartościach i pliku sortowanego o n działkach utwórz m pomocniczych kolejek, indeksowanych przez te wartości. Każda kolejka powinna mieć pojemność n działek.

2) Czytaj klucze w kolejnych rekordach sortowanego pliku. Rekord R[i] z kluczem k[i] przenieś na koniec kolejki, indeksowanej przez k[i].

3) Po przeniesieniu wszystkich rekordów skatenuj kolejki w kolejności wzrastających klu-czy.

9.3.3.Wariant łańcuchowy

W przypadku implementacji pliku sortowanego i wszystkich kolejek pomocniczych na łańcuchach odsyłaczowych algorytm jw. staje się intensywny („in situ”).

9.3.4.Uwaga dotycząca terminologii

Proces przenoszenia rekordów do kolejek jest sortowaniem (dzieleniem rekordów na sor-ty), stąd ogólnie przyjęte określanie monotonizacji jako „sortowania”.

========

10.Tablice rozproszone

10.1.Wprowadzenie

Terminy angielskie: scatter storage; hashing

Literatura: Jagielski R.: Tablice rozproszone, 1982

Algorytmy: numeryzujące klucze tekstowe; rozpraszające (mieszające, „haszujące”) rekordy; usuwające kolizje adresowe; reorganizujące tablicę

Metody łańcuchowe

10.2.Numeryzacja kluczy tekstowych

Potrzeba numeryzacji

Składanie (ang. folding) cykliczne z dodawaniem arytmetycznym

Składanie cykliczne z różnicą symetryczną („XOR”)

Składanie zygzakowe

Składanie jako metoda rozpraszania

10.3.Metody rozpraszania

10.3.1.Metoda środka kwadratu

Algorytm:

1) Znumeryzowany klucz podnieś do kwadratu

2) Z binarnej reprezentacji wyniku wybierz k środkowych bitów

Ogólna ocena metody

10.3.2.Metoda mnożenia

Obliczenie adresu początkowego:

a0 := trunc ( [(k * c) mod 1] * l )

gdzie k - klucz znumeryzowany

0x08 graphic
c - liczba rzeczywista, np. stosunek złotego podziału ( 5 + 1 ) / 2

l - długość tablicy o działkach numerowanych od 0 do l * 1

Ogólna charakterystyka metody

10.3.3.Metoda dzielenia

Obliczenie adresu początkowego:

a0 := k mod l

gdzie k - klucz znumeryzowany

l - długość tablicy o działkach numerowanych od 0 do l * 1

Warunek: l - liczba pierwsza albo pseudopierwsza (czynniki pierwsze * 20)

10.4.Algorytmy usuwania kolizji adresowych

10.4.1.Wprowadzenie

Konieczność kolizji i jakość rozpraszania

Terminologia:

rekordy czołowe, nadmiarowe i synonimiczne

Rozmieszczenie synonimów:

1) wszystkie w tablicy głównej

2) czołowy w głównej, nadmiarowe w pomocniczej

3) odsyłacz w głównej, synonimy w pomocniczej

Powiązania w łańcuchu synonimów:

1) algorytmiczne

2) odsyłaczowe

10.4.2.Metoda liniowa

ai := ( a0 + b * i ) mod l

Najprościej przyjąć b = 1 albo * 1, otrzymując:

ai := ( a0 * i ) mod l

Zalety metody: prostota; małe odległości między synonimami

Wada: skłonność do tworzenia skupień

Zalecany współczynnik zapełnienia tablicy: ≤ 80 %

10.4.3.Metoda kwadratowa, wariant prymitywny

(Jagielski, str.36)

ai := ( a0 + b * i + c * i 2 ) mod l

Najprościej przyjąć b = 0, c = 1 albo * 1, otrzymując:

ai := ( a0 * i 2 ) mod l

Przykład: l = 10; adresy: 0, 1, ..., 9; a0 = 0

Numery prób i : 1 2 3 4 5 6 7 8 9

Adresy ai : 1 4 9 6 5 6* 9* 4* 1*

Uwagi: (1) * - adresy zdublowane

(2) 2, 3, 7, 8 - adresy pominięte

10.4.4.Metoda Radkego

Warunek wstępny: l - liczba Radkego ( = liczba pierwsza spełniająca dodatkowo warunek

l = 4 * j + 3, gdzie j - dowolna liczba naturalna)

Kolejne adresy:

a1 := ( a0 + 1 2 ) mod l a2 := ( a0 * 1 2 ) mod l

a3 := ( a0 + 2 2 ) mod l a4 := ( a0 * 2 2 ) mod l

a5 := ( a0 + 3 2 ) mod l a6 := ( a0 * 3 2 ) mod l itd.

Uwagi: (1) Liczba kwadratowana nie jest już numerem próby.

(2) Liczba prób musi pozostać mniejsza od l .

(3) Kwadraty kolejnych liczb naturalnych trzeba każdorazowo obliczać albo kopiować z tablicy.

10.4.5.Różnicowanie ciągu liczb kwadratowych

Liczby naturalne: 0 1 2 3 4 5 6 7 8

Liczby kwadratowe: 0 1 4 9 16 25 36 49 64

Pierwsza różnica: 1 3 5 7 9 11 13 15

Druga różnica: 2 2 2 2 2 2 2

10.4.6.Metoda Daya

Warunek wstępny: l jest liczbą Radkego

Algorytm (wg Jagielskiego, str.38):

1: a : = a 0 ; m : = * l ;

2: znal : = false;

3: while not znal and m * l do begin

4: m : = m + 2 ;

5: a : = ( a + * m * ) mod l ;

6: test ( znal )

7: end { while }

Ogólna ocena metody

10.4.7.Metody sześcienne

(Jagielski, str.39)

Mniejsze ryzyko skupień

Większy nakład obliczeń

10.4.8.Inne metody

1) Rozpraszanie podwójne (Jagielski, str.33; ang. double hashing):

ai : = ( h1(k) + h2(k) * i ) mod l

(metoda liniowa z losowanym krokiem)

2) Szukanie losowe (HS, str.475, ang. random probing):

ai : = ( h1(k) + h2(i) ) mod l

3) Rozpraszanie wielokrotne (HS, str.465, ang. rehashing):

ai : = hi(k) albo ai : = h(i, k)

10.5.Zastosowanie odsyłaczy

(ang. chaining)

10.5.1.Problem kasowania rekordów

Zapełnianie luk po rekordach skasowanych

Markowanie rekordów martwych

10.5.2.Problem sortowania łańcuchów

Optymalizacja dostępów przez sortowanie łańcuchów

10.5.3.Zastosowanie powiązań odsyłaczowych

Przypadek 1: Wszystkie rekordy w tablicy głównej

Przypadek 2: Rekordy nadmiarowe w tablicy pomocniczej

Przypadek 3: Wszystkie rekordy w tablicy pomocniczej

(Jagielski, str.29: „tablica indeksowa”)

10.6.Algorytm reorganizujący tablicę

10.6.1.Założenie wstępne

Wszystkie rekordy w tablicy głównej

10.6.2.Potrzeba reorganizacji

1) Zmiana rozmiaru tablicy

2) Zmiana algorytmu rozpraszającego albo usuwającego kolizje

3) Oczyszczanie pamięci z rekordów martwych

10.6.2.Algorytm

1) Wprowadź i odpowiednio ustaw jednobitowe znaczniki „rekord żywy” i „rekord trwały”.

2) Sekwencyjnie przeglądaj tablicę.

3) W przypadku napotkania rekordu żywego nietrwałego (uważajmy go rekord aktualny) uruchom algorytm rozpraszający i wyznacz nim adres a0. Działkę o adresie a0 uważaj za działkę aktualną. Jeżeli działka aktualna jest wolna albo zajęta przez rekord martwy, przenieś do niej rekord aktualny i zamarkuj go jako rekord trwały. Jeżeli działka aktualna jest zajęta przez rekord żywy nietrwały, wypchnij go rekordem aktualnym. Rekord wypchnięty uważaj za nowy rekord aktualny, a dotychczasowy rekord aktualny osadź w działce i zamarkuj jako trwały. Z nowym rekordem aktualnym kontynuuj postępowanie jak z poprzednim. Jeżeli kolejny rekord przeszkadzający jest żywy i trwa-ły, uruchom algorytm usuwania kolizji i wyznacz dla rekordu aktualnego nowy adres. Działkę o tym adresie uważaj za nową działkę aktualną; kontynuuj z nią postępowanie jak poprzednio. Po osadzeniu rekordu aktualnego bez wypchnięcia rekordu żywego powróć do sekwencyjnego przeglądu.

4) Algorytm kończy pracę po dojściu sekwencyjnego przeglądu do końca tablicy.

10.7.Statystyczne porównanie metod rozpraszania

(HS, str.468, wg Luma, Yuena i Dodda, CACM, r.1971)

10.7.1.Kolizje: szukanie liniowe

(Liczby w polu głównym tabeli oznaczają średnią ilość dostępów)

0x08 graphic
Współczynnik

Zapełnienia

Metoda

Składanie

Cykliczne

Składanie

Zygzakowe

Środek

Kwadratu

Dzielenie

0,5

0,75

0,9

0,95

21,75

65,10

77,01

118,57

22,97

48,70

69,63

97,56

1,73

9,75

27,14

37,53

4,52

7,20

22,42

25,79

10.7.2.Kolizje: odsyłaczowe łańcuchy synonimów

Współczynnik

Zapełnienia

Metoda

Składanie

Cykliczne

Składanie

Zygzakowe

Środek

Kwadratu

Dzielenie

0,5

0,75

0,9

0,95

1,33

1,48

1,40

1,51

1,39

1,57

1,55

1,51

1,26

1,40

1,45

1,47

1,19

1,31

1,38

1,41

10.7.3.Wniosek

Wyniki przemawiają za metodą dzielenia z synonimami powiązanymi przez łańcuch odsyłaczowy.

11.Struktury pierścieniowe

11.1.Pierścień jednokierunkowy

11.1.1.Definicja

Struktura dynamiczna:

o podłożu pierścieniowym zmiennym,

o pokryciu zupełnym jednorodnym,

o dynamice pierścienia jednokierunkowego

11.1.2.Działki wyróżnione

Umowny początek pierścienia

Działka robocza

11.1.3.Przypadki szczególne

Pierścień elementarny

Pierścień pusty

11.1.4.Operacje proste

Sprawdzanie niepustości pierścienia

Opróżnianie pierścienia

Przesuwanie wyróżnienia roboczego na działkę początkową

Przesuwanie wyróżnienia roboczego na działkę następną

Przesuwanie wyróżnienia początkowego na działkę roboczą

Wprowadzanie elementu jako nowego elementu początkowego

Wprowadzanie nowego elementu na prawo od działki roboczej

Odczytywanie zawartości działki roboczej

Kasowanie działki położonej na prawo od roboczej

11.1.5.Przykład operacji złożonej

Przeszukiwanie pierścienia

11.1.6.Implementacje

Implementacja tablicowa zwarta i luźna

Implementacja na pierścieniu odsyłaczowym jednokierunkowym

11.1.7.Przykład zastosowania

Implementacja multizbioru z wyrównaną częstością dostępu do poszcze-gólnych egzemplarzy

11.2.Pierścień dwukierunkowy

11.2.1.Definicja

Jak pierścień jednokierunkowy, lecz z dynamiką pierścienia dwukierunko-wego

11.2.2.Działki wyróżnione i przypadki szczególne

Jak dla pierścienia jednokierunkowego

11.2.3.Operacje proste

Jak dla pierścienia jednokierunkowego, a oprócz tego:

Przesuwanie wyróżnienia roboczego na działkę poprzednią

Wprowadzanie nowego elementu na lewo od działki roboczej

Kasowanie działki położonej na lewo od roboczej

11.2.4.Przykład operacji złożonej

Przeszukiwanie pierścienia

11.2.5.Implementacje

Implementacja tablicowa zwarta i luźna

Implementacja na pierścieniu odsyłaczowym dwukierunkowym

12.Podstawowe pojęcia teorii grafów

12.1.Graf prosty nieskierowany

12.1.1.Definicja

G = ( V, E )

gdzie: V (wierzchołki, vertices lub vertexes) - dowolny zbiór

E (krawędzie, edges): E ⊆ {{v1, v2} | v1, v2 V }

Wnioski: zakaz krawędzi zapętlonych;

zakaz krawędzi równoległych

12.1.2.Podstawowe relacje między wierzchołkami i krawędziami

Incydencja między wierzchołkiem a krawędzią

Adiacencja (sąsiedztwo) między wierzchołkami

12.1.3.Niektóre szczególne przypadki grafów

Graf pusty

Graf elementarny

Wierzchołek separowany

Graf wierzchołkowy

Graf pełny

12.1.4.Pojęcie podgrafu

G = ( V, E ), G' G oznacza,

że V' V, E' E, oraz że G' = ( V', E' ) jest grafem.

12.1.5.Przykłady zastosowań

Sieć komunikacyjna

Sieć przesyłowa

Rysunek kreskowy

12.1.6.Ścieżka i pojęcia pochodne

Ścieżka prosta

Ścieżka uwikłana

Osiągalność wierzchołka v2 z wierzchołka v1

Spójność pary wierzchołków

Graf spójny

Część spójna grafu niespójnego

12.1.7.Cykl i pojęcia pochodne

Cykl prosty

Cykl uwikłany

Graf acykliczny

12.1.8.Parametry ilościowe grafu

Liczba wierzchołków

Liczba części spójnych

Stopień wierzchołka

Stopień grafu

12.1.9.Grafy etykietowane

Etykietowanie wierzchołków i krawędzi

Graf ważony

12.2.Drzewo bez korzenia

12.2.1.Definicja

Graf acykliczny spójny

12.2.2.Twierdzenie o jedynej ścieżce

Między dowolnymi wierzchołkami v1 i v2 drzewa występuje dokładnie jedna ścieżka.

12.2.3.Przykład

Drzewo rozpinające grafu spójnego ( = podgraf acykliczny, zawierający wszystkie wierzchołki i maksymalny podzbiór krawędzi grafu danego)

12.3.Drzewo z korzeniem

12.3.1.Definicja

Drzewo z korzeniem otrzymuje się z drzewa bez korzenia, powołując dowolnie wybrany wierzchołek do roli korzenia.

Terminologia: wierzchołek → węzeł

12.3.2.Podstawowe relacje między wierzchołkami i pojęcia pochodne

Relacje „przodek - potomek” i „ojciec - syn”

Rodzeństwo

Węzeł przelotowy, liść i korona drzewa

Poziom drzewa i numeracja poziomów

Ranga węzła

Ścieżka promieniowa

12.3.3.Parametry ilościowe drzewa z korzeniem

Liczba węzłów

Liczba poziomów ( = wysokość drzewa)

Stopień węzła

Stopień drzewa

12.3.4.Twierdzenie o jedynej ścieżce

W drzewie z korzeniem do każdego liścia prowadzi dokładnie jedna ścieżka promieniowa.

12.3.5.Drzewo mnogościowe

Drzewo z korzeniem, w którego rodzeństwach nie wprowadzono indeksacji ani porządku

12.3.6.Drzewo indeksowane

Drzewo z korzeniem, w którego rodzeństwach wprowadzono indeksację

12.3.7.Drzewo uporządkowane

Drzewo z korzeniem, w którego rodzeństwach wprowadzono porządki liniowe

12.3.8.Las mnogościowy

Zbiór drzew mnogościowych

12.3.9.Las indeksowany

Indeksowany zbiór drzew indeksowanych

12.3.10.Las uporządkowany

Liniowo uporządkowany zbiór drzew uporządkowanych

12.4.Graf prosty skierowany

12.4.1.Definicja

G = ( V, E )

gdzie: V - dowolny zbiór

E ⊆ {(v1, v2) | v1, v2 V ; v1v2 }

Wnioski: zakaz krawędzi zapętlonych;

zakaz krawędzi zgodnie równoległych

dozwolone krawędzie przeciwrównoległe

12.4.2.Incydencje i adiacencje

Incydencje dodatnia i ujemna

Sąsiedztwo lewostronne, prawostronne i obustronne

12.4.3.Ścieżki, cykle i pojęcia pochodne

Zwrot krawędzi należącej do ścieżki (cyklu) musi być zgodny ze zwrotem ścieżki (cyklu)

Osiągalność wierzchołka v2 z wierzchołka v1 nie implikuje osiągalności wierzchołka v1 z wierzchołka v2 .

Słaba i silna spójność pary wierzchołków

Słaba i silna spójność grafu

12.4.4. Neutralizacja grafu

Każdą krawędź bez odpowiednika przeciwrównoległego uzupełnij takim odpowiednikiem. Każdą parę krawędzi przeciwrównoległych traktuj jako krawędź nieskierowaną.

12.4.5.Zastosowania

Sieci ze skierowanymi krawędziami

12.5.Graf prosty mieszany

Graf prosty, w którym mogą występować zarówno krawędzie skierowane jak i nieskiero-wane

12.6.Multigrafy

12.6.1.Multigraf skierowany

G = ( V, E, ι )

gdzie: V - dowolny zbiór

E - dowolny zbiór rozłączny w stosunku do V

ι (funkcja incydencji): E V 2

Uwaga: Funkcja incydencji musi być funkcją zupełną.

Wnioski: 1) Krawędzie zapętlone są dozwolone.

2) Krawędzie równoległe są dozwolone.

12.6.2.Multigraf nieskierowany i mieszany

można uzyskać ze skierowanego przez całkowitą bądź częściową neutralizację

12.6.3.Zastosowanie

Sieci dowolnego charakteru.

13.Struktury drzewiaste: wprowadzenie

13.1.Definicje oparte na teorii grafów

13.1.1.Drzewiasta struktura danych

Struktura danych (na ogół: dynamiczna)

o podłożu drzewiastym (na ogół: zmiennym)

13.1.2.Podłoże drzewiaste

Drzewo lub las,

w którym węzły traktowane są jako działki podłoża,

a elementy relacji „ojciec - syn” - jako powiązania między działkami.

13.1.3.Uwagi dotyczące terminologii

1) W przypadkach, kiedy nie będzie to groziło wieloznacznością, statyczna lub dynamiczna struktura danych, której podłoże jest drzewem lub lasem, też będzie nazywana drzewem (lasem).

2) Drzewa, definiowane w oparciu o teorię grafów, będą tu nazywane drzewami grafowymi.

13.1.3.Uwaga dotycząca dynamiki

Dynamikę drzewiastych struktur danych łatwiej jest definiować wprowadzjąc rekurencyjne definicje tych struktur.

13.2.Definicje rekurencyjne

13.2.1.Uwagi wprowadzające

1) Definicje rekurencyjne pozwalają wykorzystać uprzednio wprowadzone definicje struktur dynamicznych (zbiór, tablica, lista) i przez to łatwiej definiować i klasyfikować dynamiczne struktury drzewiaste.

2) Struktury drzewiaste definiowane rekurencyjnie będą tu też nazywane drzewami rekurencyjnymi.

13.2.2.Drzewo rekurencyjne mnogościowe

Rekord o dwu polach:

1) pole korzenia (może być pokryte przez c C)

2) pole rozgałęzienia (może być pokryte przez las mnogościowy)

13.2.3.Las mnogościowy

Zbiór (w sensie mnogościowej struktury danych) drzew mnogościowych

13.2.4.Pojęcia związane

Korzeń drzewa T: pole korzenia drzewa T z pokryciem

Rozgałęzienie drzewa T: pokrycie pola rozgałęzienia drzewa T

Drzewo elementarne: drzewo o pustym rozgałęzieniu

Drzewo puste: drzewo elementarne o pustym polu korzenia

Poddrzewo główne drzewa T: element pokrycia rozgałęzienia drzewa T

Poddrzewo drzewa T:

1) drzewo T

2) poddrzewo główne drzewa T

3) poddrzewo poddrzewa głównego drzewa T

Węzeł drzewa T: korzeń poddrzewa drzewa T

Relacja „ojciec - syn” w drzewie T: zbiór par „węzeł N - korzeń poddrzewa głównego poddrzewa, którego korzeniem jest N”

13.2.5.Dynamika drzewa rekurencyjnego mnogościowego

jest zdeterminowana przez dynamikę zbioru (rozumianego jako mnogościowa struktura danych), zastosowaną do wszystkich występujących w tym drzewie rozgałęzień.

13.2.6.Związek z drzewem i lasem mnogościowym grafowym

Nietrudno zauważyć, że stan drzewa (lasu) mnogościowego rekurencyjnego, odpowiadający pewnej chwili czasu, może być traktowany jako drzewo grafowe mnogościowe (las grafowy mnogościowy), którego węzły potraktowane zostały jako działki grafowej struktury danych.

13.2.7.Drzewo rekurencyjne tablicowe

Jak drzewo rekurencyjne mnogościowe z tą różnicą, że każde występujące w tym drzewie rozgałązienie jest lasem tablicowym.

13.2.8.Las tablicowy

Tablica liniowa, której działki mogą być pokrywane przez drzewa tablicowe.

13.2.9.Związek z drzewem grafowym indeksowanym

Nietrudno zauważyć, że stan drzewa rekurencyjnego tablicowego, odpowiadający pewnej chwili czasu, może być traktowany jako drzewo grafowe indeksowane.

13.2.10.Drzewo rekurencyjne listowe

Jak drzewo rekurencyjne mnogościowe z tą różnicą, że każde występujące w tym drzewie rozgałęzienie jest lasem listowym.

13.2.11.Las listowy

Lista o działkach pokrytych przez drzewa listowe.

13.2.12.Związek z drzewem grafowym uporządkowanym

Nietrudno zauważyć, że stan drzewa rekurencyjnego listowego, odpowiadający pewnej chwili czasu, może być traktowany jako drzewo grafowe uporządkowane.

13.3.Drzewa i lasy mnogościowe

13.3.1.Lasy „Union - Find”

Relacja równoważnościowa (zwrotna, symetryczna i przechodnia)

Klasy równoważnościowe

Implementacja klas równoważnościowych na lesie mnogościowym

Operacja „Find”

Operacja „Union”

Odsyłaczowa implementacja lasu „Union - Find”

13.3.2.Algorytm Kruskala

(drzewo rozpinające o minimalnym koszcie)

Założenia:

1) graf prosty nieskierowany ważony

2) poszukiwane jest drzewo rozpinające o minimalnym koszcie

Algorytm:

1) Utwórz podgraf wierzchołkowy z wszystkich wierzchołków grafu danego. Przynależność wierzchołków do części spójnych podgrafu rejestruj przy pomocy lasu „Union - Find”.

2) Listę krawędzi grafu danego posortuj według niemalejących wag.

3) Przeglądając sekwencyjnie listę krawędzi włączaj do podgrafu każdą krawędź, incydentną z wierzchołkami należącymi do różnych części spójnych.

4) Realizację algorytmu zakończ po wyczerpaniu listy krawędzi. Otrzymany podgraf będzie poszukiwanym drzewem rozpinającym.

13.3.3.Zastosowania różne

Hierarchie o nieuporządkowanych rodzeństwach

14.Drzewa binarne

14.1.Wprowadzenie

14.1.1.Definicja drzewa binarnego

Drzewo tablicowe, w którym każde rozgałęzienie jest tablicą o dwu działkach.

Adresacja działek: np. 0 - 1, 1 - 2, L - P

Wniosek: węzeł pierwszego stopnia z synem pierwszym

≠ węzeł pierwszego stopnia z synem drugim

14.1.2.Drzewo binarne pełne

Drzewo binarne, w którym każdy poziom zawiera maksymalną liczbę węzłów

Numeracja węzłów poziomami w drzewie binarnym:

0x01 graphic

14.1.3.Parametry ilościowe w drzewie binarnym pełnym

1) Liczba węzłów na poziomie k: nk = 2k - 1

2) Ogólna liczba węzłów drzewa o h poziomach: n = 2k - 1

14.1.4.Drzewo binarne kompletne o n węzłach

Powstaje z drzewa pełnego przez odrzucenie węzłów o numerach > n

Przykład: n = 6

0x01 graphic

Wniosek: Drzewo binarne kompletne może mieć dowolną liczbę węzłów.

14.1.5.Tablicowa implementacja drzewa binarnego kompletnego

(implementacja poziomami)

0x01 graphic

Położenia synów węzła o adresie a: a1 = 2*a; a2 = 2*a + 1

Położenie ojca węzła o adresie a: a0 = a div 2

Wnioski:

1) Każda tablica liniowa może być uważana za drzewo binarne kompletne za-implementowane poziomami.

2) Strefa ojców: a l div 2 ; strefa liści: a > l div 2

14.2.Kopiec i sortowanie kopcowe

14.2.1.Kopiec

(także „stóg”, ang. heap)

Założenia:

1) Dane jest drzewo binarne kompletne o działkach pokrytych przez rekordy.

2) W każdym rekordzie jest jedno pole kluczowe.

Warunek, aby plik jw. był kopcem:

Klucz każdego ojca jest niemniejszy niż klucz któregokolwiek jego syna.

Wnioski:

1) Każde poddrzewo kopca jest kopcem.

2) Klucz korzenia kopca jest maksymalnym kluczem kopca.

14.2.2.Pseudokopiec

Założenia: jak dla kopca

Warunek: Warunek kopca jest spełniony dla wszystkich węzłów oprócz, być może, korzenia.

Wnioski:

1) Każdy kopiec jest pseudokopcem.

2) Każde drzewo spełniające założenia jw. i mające wysokość niewiększą niż 2 jest pseudokopcem.

14.2.3.Przesiewanie pseudokopca

( = operacja przeprowadzająca pseudokopiec w kopiec przez przestawianie jego węzłów)

Algorytm przesiewania:

1) Weź pod uwagę korzeń pseudokopca i tego z jego synów, który ma większy klucz. Jeżeli węzły te naruszają warunek kopca, zamień je miejscami.

2) Dotychczasowy korzeń pseudokopca stał się korzeniem poddrzewa, w którym - być może - narusza warunek kopca. Jeżeli tak jest, zamień go miejscami z sy-nem o większym kluczu.

3) Kontynuuj przemieszczanie korzenia do coraz głębszych poziomów aż przestanie on naruszać warunek kopca albo aż osiągnie pozycję liścia.

14.2.4.Kopcowanie drzewa

( = przekształcanie drzewa binarnego kompletnego spełniającego założenia jw. w kopiec)

Algorytm:

Przeglądaj sekwencyjnie strefę ojców od prawej do lewej. Dla każdego ojca przesiej poddrzewo, którego jest on korzeniem (zauważ, że poddrzewa o wysokości 2 są pseudokopcami na mocy wniosku 2 z p.14.2.2; poddrzewa wyższe są pseudokopcami, ponieważ ich poddrzewa główne zostały kopcami w toku poprzednich działań tego algorytmu). Po dojściu do korzenia drzewo będzie kopcem.

14.2.4.Sortowanie kopcowe

(także „stogowe”, ang. heapsort)

Algorytm:

1) Sortowaną tablicę liniową uważaj za implementację poziomami drzewa binar-nego kompletnego.

2) Przeprowadź sortowaną tablicę w implementację kopca. Zauważ, że w pierwszej działce znajduje się rekord z kluczem maksymalnym.

3) Zamień miejscami pierwszy i ostatni rekord sortowanej tablicy. Rekord, który znalazł się w ostatniej działce, jest na swojej definitywnej pozycji. Wyłącz tę pozycję z dalszego sortowania.

4) Zauważ, że pozostawiona do dalszego sortowania część tablicy stanowi implementację pseudokopca. Przesiej ten pseudokopiec i przejdź do punktu 3 algorytmu.

5) Algorytm kończy działanie, gdy nie posortowana część tablicy osiągnie długość 1.

Ogólna ocena metody:

Złożoność liniowo-logarytmiczna bez niebezpieczeństwa ukwadratowienia.

Statystyczny czas sortowania: około 1,5 qs.

14.3.Rekurencyjne implementacje drzew binarnych na listach

Przykład: wyrażenie a = b / ( c2 + d2 )

Reprezentacja rysunkowa:

0x01 graphic

1) Implementacja LKP (infiksowa, wymaga użycia nawiasów albo zastosowania konwencji, zastępującej nawiasy):

b / (( c ** 2 ) + ( d ** 2 ))

2) Implementacja KLP (prefiksowa, zwana notacją Łukasiewicza albo „polską”, nie wymaga użycia nawiasów):

/ b + ** c 2 ** d 2

3) Implementacja LPK (postfiksowa, beznawiasowa, zwana też „odwrotną polską” = IPN = Inverse Polish Notation, szczególnie dogodna przy automatycznym obliczaniu wartości wyrażeń):

b c 2 ** d 2 ** + /

14.4.Implementacje odsyłaczowe

14.4.1.Implementacja o trzech odsyłaczach w rekordzie

0x01 graphic

(Umożliwia szybkie przechodzenie w dół i w górę drzewa z dowolnego rekordu)

14.4.2.Implementacja o dwóch odsyłaczach w rekordzie

0x01 graphic

(Wymaga wejścia przez korzeń i notowania przejrzanych węzłów w notatniku stoso-wym)

14.5.Binarne drzewa poszukiwań

(ang. BST = Binary Search Trees)

14.5.1.Wprowadzenie

BST = drzewo binarne o działkach pokrytych przez rekordy; w każdym rekordzie jedno pole kluczowe

Zasady wprowadzania nowego rekordu:

1) Rekord wprowadza się przez korzeń.

2) Rekord o kluczu mniejszym (większym) od klucza rekordu aktualnego kieruje się do lewego (prawego) poddrzewa tego rekordu.

3) Każdy nowo wprowadzony rekord staje się nowym liściem drzewa.

Zasady odszukiwania rekordu o zadanym kluczu wzorcowym:

1) Przeglądać drzewo począwszy od korzenia.

2) Jeżeli klucz wzorcowy jest mniejszy (większy) od klucza rekordu aktualnego, wybierać lewe (prawe) podrzewo.

3) Koniec przeszukiwania (z wynikiem negatywnym) - po dojściu do liścia.

14.5.2.Drzewo binarne zygzakowe

Oprócz jedynego liścia wszystkie węzły są pierwszego stopnia.

Przypadki szczególne: drzewa binarne liniowe (lewoskośne i prawoskośne).

14.5.3.Złożoność przeszukiwania w drzewie BST

Wniosek z zasad wprowadzania nowego rekordu: Kształt drzewa zależy od wartości kluczy we wprowadzanych rekordach oraz od kolejności, w jakiej rekordy są wprowadzane.

Złożoność przeszukiwania dla drzewa liniowego: liniowa

Złożoność przeszukiwania dla drzewa zbliżonego do pełnego: logarytmiczna

Optymalizacja drzewa BST przez sortowanie

14.6.Drzewa AVL

(skrót „AVL” od nazwisk autorów: Adelsona-Velskiego i Landisa)

14.6.1.Drzewa zrównoważone

(ang. balanced, „wyważone”)

Definicja 1: W każdej parze bratnich poddrzew wartość bezwzględna różnicy między ilościami węzłów nie przekracza liczby 1.

Definicja 2 (stosowana w przypadku drzew AVL): W każdej parze bratnich poddrzew wartość bezwzględna różnicy między ich wysokościami nie przekracza liczby 1.

Wniosek: Czas przeszukiwania drzewa zrównoważonego zależy logarytmicznie od ogólnej ilości jego węzłów.

14.6.2.Dynamika drzewa AVL: wprowadzanie rekordu

1) Wprowadź rekord jak w drzewie BST, odnotowując ścieżkę, po której był wpro-wadzany.

2) Przeglądając ścieżkę od końca sprawdzaj zrównoważenie kolejnych węzłów.

3) W przypadku wykrycia węzła niezrównoważonego utwórz z niego i z dwu wę-złów poprzednio przejrzanych (syna i wnuka) „ośrodek rotacji”.

4) Zrealizuj rotację według zasad podanych na następnej planszy. Po wykonaniu rotacji dalsza kontrola zrównoważenia węzłów jest zbędna.

14.6.3.Rotacje LL i LR

Stan przed rotacją:

0x01 graphic

Stan po rotacji:

0x01 graphic

Rotacje RL i RR są lustrzanymi odbiciami rotacji jw.

15.Drzewa pozycyjne i listowe

15.1.Drzewa pozycyjne

(ang. trie indexing, prawdopodobnie od „retrieval”)

15.1.1.Założenia dotyczące struktury

1) Drzewo tablicowe. Rekordami pokryte wyłącznie liście.

3) W każdym rekordzie klucz k rozpada się na l zhierarchizowanych kluczy częściowych k1, k2, ..., ki, ..., kl .

4) Na i - tym poziomie drzewa rozgałęzienie indeksowane jest przez zbiór dopuszczalnych wartości klucza ki .

15.1.2.Założenia dotyczące dynamiki

1) Nowy rekord wprowadza się przez korzeń.

2) Przez i - ty poziom przeprowadza się rekord, kierując go do poddrzewa indeksowanego przez aktualną wartość klucza ki .

3) Jeżeli poddrzewo, do którego należałoby wprowadzić rekord, jest puste, należy w tym miejscu utworzyć dla niego poddrzewo elementarne.

4) Po utworzeniu nowego poddrzewa elementarnego proces wstawiania nowego rekordu należy zakończyć.

15.1.3.Implementacja odsyłaczowa

Rekord implementujący węzeł przelotowy na i - tym poziomie powinien być tablicą o działkach indeksowanych przez dopuszczalne wartości klucza ki . Działki powinny być pokryte przez odsyłacze do korzeni odpowiednich poddrzew.

Rekord implementujący liść może być zredukowany do pola korzenia, pokrytego przez rekord implementowany.

15.1.4.Ogólna ocena i zastosowanie

Drzewo pozycyjne jest strukturą o małym nakładzie czasu na odszukiwanie, ale niezbyt oszczędną, jeżeli chodzi o zapotrzebowanie na pamięć. Bywa zalecane do systemów dialogowych, gdy zachodzi potrzeba szybkiego rozpoznawania wprowadzanych wyrazów.

15.2.Implementacje drzew listowych na listach

15.2.1.Implementacja drzewa o węzłach przelotowych niepustych

Przykład drzewa:

0x01 graphic

Implementacja listowa:

A(B(F, G), C, D(H, I, J), E)

15.2.2.Implementacja drzewa koronowego

Założenia:

1) Drzewo jak w poprzednim przykładzie

2) Węzły przelotowe puste

Implementacja listowa:

((F, G), C, (H, I, J), E)

15.2.3.Uwaga o implementacjach postfiksowych

Nie stosowane.

15.3.Odsyłaczowe implementacje drzew listowych

5.3.1.Implementacja czteroodsyłaczowa

0x01 graphic

15.3.2.Implementacja trójodsyłaczowa

0x01 graphic

Uwaga: Przeglądanie z zastosowaniem tej implementacji ta wymaga:

1) Wejścia do drzewa przez korzeń

2) Prowadzenia stosowego notatnika przejść przez węzły

15.3.3.Implementacja dwuodsyłaczowa

0x01 graphic

15.3.4.Implementacja dwuodsyłaczowa z bitem powrotu

0x01 graphic

Wyjaśnienie: W przypadku gdy P = 1 odsyłacz prawy wskazuje na ojca, dlatego nie ma potrzeby prowadzenia notatnika przejść przez węzły.

15.4.Zastosowania drzew listowych

Hierarchie z porządkiem liniowym w każdym rodzeństwie, w szczególności implementacja drzew mnogościowych, sztucznie rozbudowanych o porządki liniowe w rodzeństwach.

16.Struktury grafowe

16.1.Klasyfikacja grafowych struktur danych

16.1.1.Według rodzaju grafu

Grafowa struktura danych może być oparta:

1) na grafie prostym nieskierowanym

2) na grafie prostym skierowanym

3) na multigrafie nieskierowanym

4) na multigrafie skierowanym

16.1.2.Według sposobu wykorzystania grafu

Jako działki podłoża mogą być wykorzystane:

1) wierzchołki grafu ( = struktura wierzchołkowa)

(wtedy krawędzie odgrywają rolę powiązań między działkami)

2) krawędzie grafu ( = struktura krawędziowa)

(np. w grafie ważonym)

3) wierzchołki i krawędzie ( = struktura wierzchołkowo-krawędziowa)

(rolę powiązań odgrywają elementy relacji incydencji)

16.1.3.Według regularności grafu

Podłoże struktury grafowej może być:

1) regularne (np. w przypadku tablicy wielowymiarowej)

2) nieregularne

16.2.Struktury regularne

(por.Turski: „Struktury danych”)

16.2.1.Przykład: tablica trójwymiarowa

0x01 graphic

16.2.2.Linearyzacja leksykograficzna

(najszybciej zmienia się wskaźnik ostatni):

A(1, 1, 1), A(1, 1, 2), A(1, 2, 1), A(1, 2, 2), ..., A(4, 3, 2)

16.2.3.Linearyzacja antyleksykograficzna

(najszybciej zmienia się wskaźnik pierwszy):

A(1, 1, 1), A(2, 1, 1), ..., A(4, 1, 1), A(1, 2, 1), ..., A(4, 3, 2)

16.3.Macierze niepełne

16.3.1.Wprowadzenie

Macierz = tablica dwuwymiarowa

Linearyzacja leksykograficzna = linearyzacja wierszowa

Linearyzacja antyleksykograficzna = linearyzacja kolumnowa

Macierz niepełna = macierz o dużej liczbie elementów trywialnych (np. działki puste, wyzerowane albo wyspacjowane) lub powtarzających się

16.3.2.Macierz pasmowa

Elementy nietrywialne na przekątni głównej i w pasie symetrycznie rozmieszczonym względem tej przekątni:

0x01 graphic

16.3.3.Macierze trójkątne

0x01 graphic

(Część nietrywialna poniżej linii podziału mieści się w części pustej powyżej tej linii)

16.3.4.Macierze symetryczne

Nietrywialna część macierzy symetrycznej jest macierzą trójkątną dużą.

16.3.5.Macierze antysymetryczne

Nietrywialna część macierzy antysymetrycznej jest macierzą trójkątną małą.

16.4.Macierze rzadkie

16.4.1.Definicja i zastosowanie

Macierze o niewielkiej liczbie elementów nietrywialnych (np. kilka procent; macierzami takimi są z reguły macierze adiacencji i macierze incydencji implementujące strukturę grafu).

16.4.2.Implementacja na triadach (trójkach)

Triada = rekord o trzech polach:

i - numer wiersza; j - numer kolumny; A(i, j) - pokrycie działki

Struktura implementująca: lista o działkach pokrytych przez triady

Zaleta: prostota struktury

Wada: uciążliwość przeszukiwania

16.4.3.Implementacja odsyłaczowa

0x01 graphic

Zalety: elastyczność; łatwość przeglądania wierszami i kolumnami

16.5.Struktury wierzchołkowe oparte na grafach prostych nieskierowanych

16.5.1.Założenia dotyczące wyróżnień

1) Dogodnie jest wprowadzić dwa wyróżnienia wierzchołków: „pierwsze” i „drugie”

2) Jeżeli wierzchołki wyróżnione są sąsiadami, to łącząca je krawędź też będzie uważana za wyróżnioną.

16.5.2.Operacje proste

1) Opróżnianie struktury

2) Dołączanie wierzchołka separowanego

3) Wyróżnianie dowolnego wierzchołka

4) Dołączanie krawędzi między wierzchołki wyróżnione

5) Przenoszenie wyróżnienia na dowolny wierzchołek sąsiedni

6) Zmiana pokrycia wierzchołka wyróżnionego

7) Usuwanie wyróżnionej krawędzi

8) Usuwanie wyróżnionego wierzchołka separowanego

16.5.3.Wybrane operacje złożone

1) Przeglądanie grafu

2) Budowa drzewa rozpinającego

3) Badanie spójności grafu

4) Badanie acykliczności grafu

5) Badanie planarności grafu

6) Poszukiwanie maksymalnego podgrafu pełnego („kliki”)

16.5.4.Przeglądanie w głąb („stosowe”)

(dotyczy grafu spójnego albo części spójnej grafu niespójnego)

1) Wyróżnij dowolny wierzchołek, zamarkuj go jako przeglądnięty i odnotuj w stosowym notatniku.

2) Zbadaj, czy wierzchołek odnotowany na wierzchołku notatnika ma nie zamarkowanego sąsiada. Jeżeli ma, wyróżnij go, zamarkuj i odnotuj w notatniku.

3) Kontynuuj czynność z punktu (2) aż okaże się, że wierzchołek grafu odnotowany na wierzchołku stosu nie ma nie zamarkowanego sąsiada. Strąć wtedy bezużyteczną notatkę z wierzchołka stosu i wróć do punktu (2).

4) Realizacja algorytmu kończy się z chwilą opróżnienia stosu.

16.5.5.Przeglądanie wszerz („kolejkowe”)

(również do grafu spójnego)

Jak przeglądanie w głąb z tą różnicą, że nowo zamarkowane wierzchołki odnotowuje się na końcu notatnika kolejkowego, a przejścia na nowy wierzchołek dokonuje się na podstawie notatki umieszczonej na początku tego notatnika.

16.5.6.Budowa drzewa rozpinającego oparta na przeglądaniu w głąb lub wszerz

Do drzewa należy włączać wszystkie kolejno markowane wierzchołki i wszystkie efektywnie wykorzystane krawędzie. Przez krawędź efektywnie wykorzystaną należy rozumieć krawędź, przez którą nastąpiło przejście z poprzednio zamarkowanego wierzchołka na wierzchołek nowo markowany.

Nietrudno zauważyć:

1) że zarówno w przypadku przeglądania tak stosowego jak i kolejkowego kształt drzewa rozpinającego zależy od zasady, według której wybiera się nie zamarkowanego sąsiada w przypadku, gdy takich sąsiadów jest więcej niż jeden;

2) że drzewo rozpinające budowane w oparciu o przeglądanie stosowe jest zwykle bardziej smukłe niż drzewo budowane w oparciu o przeglądanie kolejkowe.

16.5.7.Implementacja tablicowa z zastosowaniem macierzy adiacencji

1) Ustal maksymalną dopuszczalną liczbę wierzchołków N w implementowanym grafie

2) Utwórz tablicę liniową W o długości N. W działkach tej tablicy umieść reprezentacje wierzchołków grafu implementowanego.

3) Utwórz macierz kwadratową A o boku N (będzie to macierz adiacencji grafu imple-mentowanego). Zarówno wiersze jak i kolumny tej macierzy powinny być indeksowane przez wierzchołki implementowanego grafu. Każda działka macierzy powinna mieć pojemność 1b.

4) Do działki A(i, j) macierzy A wpisz 1, jeżeli i - ty wierzchołek grafu implementowanego jest adiacentny z wierzchołkiem j - tym. W przeciwnym razie wpisz do działki 0.

Wnioski:

1) Istotnym utrudnieniem, wprowadzanym przez implementację tablicową, jest konieczność wprowadzania górnego ograniczenia liczby wierzchołków implementowanego grafu.

2) Ponieważ relacja adiacencji jest symetryczna, symetryczna jest też macierz A ( A(i, j) = A(j, i) ).

3) W przypadku grafu pełnego macierz A jest w całości pokryta przez jedynki. W przypadku przeciętnym (np. kilkadziesiąt wierzchołków, każdy ma kilku sąsiadów) A będzie macierzą rzadką.

16.5.8.Implementacja z zastosowaniem listy krawędzi

1) Utwórz listę W (lista wierzchołków). Element W(i) listy W powinien reprezentować i - ty wierzchołek implementowanego grafu.

2) Utwórz listę K (lista krawędzi), której każdy element będzie odpowiadał jednej z kra-wędzi implementowanego grafu. Krawędź, łącząca wierzchołek i - ty z j - tym powinna być w liście K reprezentowana przez rekord o dwu polach; pierwsze z tych pól powinno zawierać odsyłacz p(i) do elementu W(i), drugi - odsyłacz p(j) do elementu W(j) listy W. Każda krawędź powinna być w liście K reprezentowana jednokrotnie, bądź to jako para (p(i), p(j)), bądź jako para (p(j), p(i)).

Wniosek:

Jest oczywiste, że przypadkowa na ogół kolejność elementów w liście K nie sprzyja szyb-kiemu odszukiwaniu sąsiadów danego wierzchołka. Przeszukiwanie to musi - w ogólnym przypadku - objąć wszystkie elementy tej listy, a w obrębie danego elementu - obydwa pola.

16.5.9.Implementacja z listami sąsiadów

Po utworzeniu listy W jak w poprzednio omówionej implementacji dołącz do każdego elementu W(i) tej listy listę odsyłaczy do tych jej elementów, które reprezentują sąsiadów i - tego rekordu implementowanego grafu.

Ocena ogólna:

Rozwiązanie wymaga utrzymywania wielu pomocniczych list sąsiadów, ale umożliwia szybkie dotarcie do każdego z nich, co jest istotną zaletą tej implementacji z punktu widzenia potrzeb algorytmu przeglądania grafu.

Ćwiczenie:

Zaleca się uzupełnienie ostatnio zreferowanej metody tak, aby mogła ona służyć do implementacji nie tylko danego grafu, ale także jedego z jego rozpinających drzew.

16.6.Struktury wierzchołkowe oparte na grafach prostych skierowanych

16.6.1.Operacje proste

Jak dla grafów nieskierowanych z tą różnicą, że w przypadku wstawiania nowej krawędzi między wierzchołki v1 i v2 należy odróżnić podprzypadek wstawiania krawędzi (v1, v2) od podprzypadku wstawiania krawędzi (v2, v1). Podobnie krawędź (v1, v2) należy odróżnić od krawędzi (v2, v1) w przypadku kasowania krawędzi wstawionej między wyróżnione wierzchołki v1 i v2.

16.6.2.Implementacja z zastosowaniem tablicy adiacencji

Jak dla grafów nieskierowanych z tą różnicą, że działkę A(i, j) macierzy A należy traktować jako odpowiednik uporządkowanej pary (vi, vj), różnej od uporządkowanej pary (vj, vi). Macierz A tym samym nie musi już być symetryczna.

16.6.3.Implementacja z zastosowaniem listy krawędzi

Odróżniając pary (vi , vj ) od par (vj , vi ) należy w liście K wprowadzić zasadę, że pierwsze pole w rekordzie pokrywającym działkę listy odnosi się do początku danej krawędzi, a drugie do jej końca.

16.6.4.Implementacja z listami sąsiadów

Do każdego elementu listy W należy dołączyć dwie listy odsyłaczy do rekordów reprezentujących wierzchołki sąsiednie, a mianowicie listę odsyłaczy do sąsiadów lewostronnych oraz listę odsyłaczy do sąsiadów prawostronnych. Można też pozostawić jedną listę sąsiadów, wprowadzając do każdego jej elementu dwubitowe pole techniczne informujące, czy w danym przypadku chodzi o sąsiada lewo-, prawo-, czy obustronnego.

16.7.Struktury wierzchołkowo-krawędziowe oparte na grafach prostych skierowanych

16.7.1.Wprowadzenie

Wierzchołki grafu implementowanego powinny być reprezentowane przez rekordy, pokrywające działki tablicy lub listy W; krawędzie powinny być reprezentowane przez rekordy pokrywające działki tablicy lub listy K. Incydencje między wierzchołkami a kra-wędziami mogą być reprezentowane przez macierz incydencji albo przez odsyłacze do incydentnych krawędzi lub wierzchołków.

16.7.2.Macierz incydencji

Załóżmy prostokątną macierz incydencji I o wierszach indeksowanych przez wierzchołki i kolumnach indeksowanych przez krawędzie grafu implementowanego. Działka I(i, j) tej macierzy, należąca do jej i - tego wiersza i j - tej kolumny, powinna zawierać informację, czy wierzchołek vi i krawędź kj są ze sobą incydentne oraz jaka jest orientacja tej incydencji (ujemna czy dodatnia, tj. czy vi jest początkiem czy końcem kj). Łatwo zauważyć, że wystarczą tu trzy dopuszczalne wartości pokrycia działki I(i, j), np. 1 dla incydencji ujemnej, 2 dla dodatniej i 0 dla braku incydencji.

16.7.3.Rozszerzona lista krawędzi

O elemencie K(j) listy K można założyć, że oprócz reprezentacji krawędzi kj zawiera on odsyłacze do tych elementów listy W, które reprezentują początek i koniec tej krawędzi. Rozszerzenie takie umożliwia szybkie przejście z krawędzi na incydentne z nią wierzchołki, natomiast przejście odwrotne, tzn. z wierzchołka na incydentną krawędź wymaga tu przeglądnięcia obydwu odsyłaczy we wszystkich elementach listy K.

16.7.4.Listy krawędzi incydentnych

Poprzednio omówioną implementację można rozszerzyć o dołączone do każdego elementu W(i) listy W dwie listy odsyłaczy: do elementów listy K odpowiadających krawędziom ujemnie bądź dodatnio incydentnym z wierzchołkiem vi. Uzupełnienie takie umożliwia szybkie przechodzenie z rekordu wierzchołka na rekordy incydentnych krawędzi.

16.8.Struktury wierzchołkowo-krawędziowe oparte na multigrafach skierowanych

16.8.1.Wprowadzenie

Nowościami w stosunku do grafów prostych, jakie dopuszcza multigraf skierowany, są:

1) dopuszczalność krawędzi zapętlonych oraz

2) dopuszczalność krawędzi zgodnie równoległych.

Należy zwrócić uwagę, że w stosunku do wierzchołka, będącego równocześnie jej początkiem i końcem, krawędź zapętlona wykazuje jednocześnie dwa rodzaje incydencji: ujemną i do-datnią.

16.8.2.Implementacja krawędzi zapętlonej w przypadku posłużenia się macierzą incydencji

Zbiór dopuszczalnych pokryć działki macierzy należy rozszerzyć o nową wartość (np. 3), oznaczającą podwójną incydencję.

16.8.3.Implementacja krawędzi zapętlonej w przypadku posłużenia się listami krawędzi incydentnych

Krawędź podwójnie incydentną można umieszczać jednocześnie na liście krawędzi incy-dentnych ujemnie i na liście krawędzi incydentnych dodatnio, albo też można utworzyć przy rekordzie wierzchołka trzecią listę, tzn. listę krawędzi podwójnie incydentnych.

16.8.4.Krawędzie zgodnie równoległe

Poprzednio omówione rozwiązania, dotyczące implementacji struktur opartych na grafach skierowanych prostych umożliwiają implementację krawędzi zgodnie równoległych w strukturach opartych na multigrafach bez jakichkolwiek nowych komplikacji.

=====

17.Dane w pamięci niejednorodnej

17.1.Wprowadzenie

17.1.1.Pamięć operacyjna

Struktura zapisu:

Tablica liniowa adresowana

Dynamika dostępu:

Czas przejścia jest krótki i nie zależy od adresów bieżącego i docelowego.

Zastosowanie:

Wykorzystanie pamięci operacyjnej jest konieczne przy operacjach wykorzystujących pamięć zewnętrzną.

17.1.2.Pamięć taśmowa

Struktura zapisu:

Standard fizyczny: szerokość taśmy 1/2”, 9 ścieżek ( 1 B + kontrola parzystości), gęstość podłużna np. 32 rządki/mm, prędkość odczytu i zapisu np. 4 m/s, długość taśmy na rolce np. 720 m.

Przerwa międzyblokowa (o długości np. 20 mm), przewidziana na hamowanie, postój i rozbieg układu głowic powoduje, że efektywna podłużna gęstość zapisu waha się między około 0 do blisko 100 %.

Długość bloku determinowana jest przez pojemność buforów wyjściowego i wejścio-wego.

Dynamika dostępu:

Czas przejścia jest w przybliżeniu proporcjonalny do odległości między blokami aktualnym i docelowym i może się wyrażać w dziesiątkach sekund, a nawet w minutach.

Zastosowanie:

Praktycznie zredukowane do roli pamięci archiwalnej.

17.1.3.Pamięć dyskowa

Struktura zapisu:

Tablica wielowarstwowa, adres - w ogólnym przypadku - hierarchiczny pięcio-członowy. Człony adresu:

1) oznaczenie pakietu wymiennego albo jednostki napędowej

2) numer cylindra w obrębie pakietu

3) numer ścieżki w obrębie cylindra

4) numer sektora w obrębie ścieżki

5) numer jednostki podstawowej (np. bajtu) w obrębie sektora

Dynamika dostępu:

Czas przełączenia na inną jednostkę napędową albo na inną ścieżkę w obrębie tego samego cylindra jest pomijalnie mały.

Czas przejścia grzebienia głowic na inny cylinder jest rzędu 0,1 s.

Czas oczekiwania na żądany sektor waha się od zera do czasu pełnego obrotu pakietu, wartość średnia = czas półobrotu pakietu, rząd wielkości 0,01 s.

Zalecenia:

1) Unikać rozmieszczania pliku na kilku różnych cylindrach tej samej jednostki napędowej.

2) Unikać częstych dostępów dla wyeliminowania wielokrotnych oczekiwań.

3) Dążyć do obejmowania jednorazową transmisją możliwie dużej ilości potrzebnych danych.

Zastosowanie:

Podstawowy rodzaj pamięci masowej o względnie krótkim czasie dostępu.

17.2.Pamięć taśmowa

17.2.1.Uwaga wstępna

Pamięć taśmowa była w przeszłości podstawowym rodzajem pamięci masowej. Niektóre algorytmy, opracowane dla pamięci taśmowej, mają obecnie zastosowanie także w od-niesieniu do pamięci dyskowej.

17.2.2.Dopisywanie i kasowanie informacji

Dopisywanie nowych informacji do taśmy i kasowanie tych informacji dopuszczalne jest tylko na końcu aktualnego zapisu.

17.2.3.Modyfikacja zapisów

Modyfikacja informacji zapisanych na taśmie może być realizowana tylko w trybie transak-cyjnym.

17.3.Sortowanie taśmowe

17.3.1.Wprowadzenie

Sortowanie taśmowe obejmuje dwa etapy:

1) etap tworzenia (możliwie długich) serii początkowych,

2) etap scalania serii.

17.3.2.Tworzenie serii początkowych metodą buforową

1) Utwórz w pamięci operacyjnej możliwie duży bufor sortowania.

2) Napełnij bufor rekordami z czoła taśmy wejściowej.

3) Posortuj zawartość bufora dowolną dobrą metodą (np. „Quicksort” lub „Heapsort”)

4) Wyprowadź posortowane rekordy na taśmę wyjściową.

5) Powtarzaj punkty (2) - (4) jak wyżej do wyczerpania taśmy wejściowej.

Uwaga: Serie początkowe tworzone metodą buforową mają jednakową objętość, równą pojemności bufora sortowania.

17.3.3.Tworzenie serii początkowych metodą przelotową

1) Utwórz w pamięci operacyjnej możliwie duży bufor sortowania.

2) Napełnij bufor rekordami z czoła sortowanego pliku.

3) Z rekordów umieszczonych w buforze sortowania utwórz kopiec odwrócony (tj. z kluczem minimalnym w korzeniu)

4) Na taśmę wyjściową wyprowadzaj rekord z korzenia kopca umieszczonego w buforze bądź z czoła taśmy wejściowej kierując się zasadą, że klucz rekordu przenoszonego na wyjście powinien być niemniejszy niż klucz poprzednio wyprowadzonego tam rekordu, ale poza tym jak najmniejszy.

5) Jeżeli rekord z korzenia kopca wyprowadziłeś na wyjście, wprowadź do korzenia rekord z taśmy wejściowej i przesiej otrzymany w ten sposób pseudokopiec.

6) Jeżeli zarówno w korzeniu kopca jak i na czole taśmy wejściowej występują klucze mniejsze niż klucz ostatnio wyprowadzonego rekordu, wybierz mniejszy z tych kluczy i rozpocznij nim nową serię.

7) Kontynuuj algorytm aż do wyczerpania pliku wejściowego.

Uwaga: Serie początkowe tworzone metodą przelotową mają niejednakową objętość, na ogół większą jednak od pojemności bufora sortowania.

17.3.4.Scalanie na trzech taśmach z redystrybucją

0x01 graphic

17.3.5.Scalanie na czterech taśmach bez redystrybucji

0x01 graphic

17.4.Scalanie taśmowe wielofazowe

17.4.1.Ciąg Fibonacciego

F0 = 0; F1 = 1; Fk = F k - 1 + Fk - 2 ( dla k = 2, 3, ...)

Wniosek: Fk = F k + 2 - Fk + 1 ( dla k = 0, 1, 2, ...)

Piersze wyrazy ciągu: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89

17.4.2.Scalanie wielofazowe

1) Dopełnij ciąg serii początkowych seriami pustymi tak, aby ogólna liczba serii N była liczbą Fibonacciego Fn .

2) Podziel zbiór serii tak, aby w pierwszej części znalazło się Fn - 1 serii, a w drugiej Fn - 2 . Nagraj pierwszą część na taśmę A, a drugą na taśmę B.

3) Scalaj jedną serię z taśmy A z jedną serią z taśmy B aż do opróżnienia taśmy B. Serie scalone lokuj na taśmie C. Po ukończeniu scalania na taśmie A pozostanie Fn - 3 serii, na taśmie C będzie ich Fn - 2 , a taśma B będzie oczywiście pusta.

4) Powtarzaj scalanie serii z dwóch niepustych taśm na trzecią początkowo pustą aż do uzyskania jednej serii, tzn. zmonotonizowanego pliku.

17.4.3.Przykład

N = 144. Na taśmę A nagrywam 89 serii, na taśmę B - 55. Liczby serii na poszczególnych taśmach po ukończeniu kolejnych faz będą się przedstawiały jak poniżej:

0x08 graphic
0x08 graphic
0x08 graphic
0x08 graphic

Taśma L i c z b y s e r i i

0x08 graphic
0x08 graphic
0x08 graphic
0x08 graphic
0x08 graphic
0x08 graphic
0x08 graphic
0x08 graphic
0x08 graphic
0x08 graphic
0x08 graphic
A 89 34 - 21 8 - 5 2 - 1 -

B 55 - 34 13 - 8 3 - 2 1 -

C - 55 21 - 13 5 - 3 1 - 1

0x08 graphic

17.5.Sortowanie dyskowe

17.5.1.Wprowadzenie

1) Sortowanie dyskowe przebiega jak taśmowe z tą różnicą, że dla przyspieszenia scalania zaleca się, aby było to scalanie wielostrumieniowe.

2) W przypadku scalania wielostrumieniowego zaleca się, aby dla przyspieszenia poszukiwań minimalnego klucza w zbiorze czołowych rekordów poszczególnych strumieni wejściowych wspomóc się zastosowaniem drzewa turniejowego.

17.5.2.Drzewo turniejowe

(ang. tournament tree)

W przypadku wielostrumieniowego scalania jest to drzewo binarne pełne, w którym:

1) liście pokryte są przez klucze czołowych rekordów poszczególnych strumieni wejś-ciowych;

2) klucz ojca jest równy mniejszemu z kluczy synów.

Zastosowanie drzewa turniejowego do odszukiwania rekordu czołowego z minimalnym kluczem: rozpoczynając od korzenia przechodź na syna z mniejszym kluczem, aż doj-dziesz do liścia.

Korektura drzewa po przeniesieniu wybranego rekordu do strumienia wyjściowego: wystarczy sprawdzać i korygować węzły na ścieżce promieniowej od liścia, w którym nastąpiła wymiana, do korzenia.

17.6.Pamięć dyskowa: sieci odsyłaczowe

17.6.1.Uwaga wstępna

Ze względu na długi zazwyczaj okres przechowywania zapisów dyskowych i wynikające stąd ryzyko ich sprzętowego lub programowego uszkodzenia zaleca się, aby tworzone na dyskach sieci odsyłaczowe wyposażane były w nadmiarowe powiązania zabezpiecza-jące.

17.6.2.Przykłady powiązań zabezpieczających

1) Długodystansowe powiązania zabezpieczające w łańcuchu lub pierścieniu odsyłaczowym

2) Drzewo nizane (HS, str.239; ang. threaded tree), w którym puste pola odsyłaczowe wykorzystuje się na zabezpieczające odsyłacze do sąsiadów w porządku infiksowym

17.7.Pamięć dyskowa: tablice rozproszone

17.7.1.Uwaga wstępna

Zaleca się, aby dla uniknięcia częstych transmisji małych ilości danych stosować sekcyjną organizację tablic rozproszonych.

17.7.2.Tablica rozproszona: organizacja sekcyjna

Sekcyjna organizacja tablicy rozproszonej polega:

1) na zgrupowaniu działek tablicy w jednakowej wielkości sekcje, rozmiarem zbliżone do optymalnej objętości jednorazowo transmitowanej porcji informacji

2) na przejściu z adresowego dostępu do działki na adresowy dostęp do sekcji i sekwenyjny dostęp do działki w obrębie sekcji

17.8.Pamięć dyskowa: drzewa Bayera

(„B-drzewa”, por. Wirth, „Algorytmy + struktury”, str.257)

17.8.1.Struktura drzewa

1) Węzeł drzewa Bayera n - tego stopnia jest tablicą o 2n „dużych” działkach, zawierającą nr monotonicznie uszeregowanych rekordów r(1), r(2), ..., r(nr) z kluczami - kolejno - k(1), k(2), ..., k(nr). Dla korzenia drzewa powinno być przy tym 1 nr 2n , dla pozostałych węzłów - n nr 2n .

2) Oprócz działek dużych węzeł przelotowy drzewa powinien zawierać nr + 1 działek „małych”, rozmieszczonych jak na poniższym rysunku, przy czym działka mała, umieszczona między działkami z rekordami r(i) i r(i +1), powinna zawierać odsyłacz do korzenia poddrzewa mieszczącego rekordy o kluczach z przedziału ( k(i), k(i +1) ).

0x01 graphic

3) Stopień drzewa powinien być tak dobrany, aby objętość węzła była zbliżona do optymalnej objętości jednorazowo transmitowanej porcji informacji.

17.8.2.Dynamika drzewa

Z dynamiką drzewa Bayera (przeszukiwanie drzewa, wprowadzanie nowego rekordu i usu-wanie rekordu uprzednio wprowadzonego) studenci powinni się zapoznać według powyżej cytowanej monografii N.Wirtha.

17.8.3.Ocena ogólna

Struktura i dynamika drzew Bayera jest trafnie dobrana do technicznych warunków współpracy między pamięcią operacyjną a pamięcią dyskową, w związku z czym drzewa te są chętnie stosowane jako środek organizacji dużych plików, służących do przechowywania i odszukiwania rekordów jednakowego typu.

17.9.Pliki indeksowe

17.9.1.Wprowadzenie

W przypadku dużych plików korzystne jest ograniczenie poszukiwania do indeksu (skorowidza), w którym przechowywane są tylko klucze rekordów oraz adresy, pod którymi przechowywane są same rekordy.

17.9.2.Indeksy pierwotne i wtórne

Klucz pierwotny = klucz rozmieszczenia

Klucze wtórne = pozostałe klucze

Indeks pierwotny (wtórny): indeks, w którym poszukuje się adresu rekordu na podstawie jego klucza pierwotnego (wtórnego)

Objętość indeksu pierwotnego może być znacznie mniejsza niż objętość indeksu wtórnego, jeżeli indeks ten ogranicza się do ewidencji sekcji pliku głównego

Sumaryczna objętość indeksów przewyższa niekiedy objętość pliku głównego.

17.9.3.Organizacja indeksu

1) Monotoniczna

2) Algorytmiczna

3) Wielostopniowa

18.Kompresja danych

18.1.Wprowadzenie

18.1.1.Terminologia

1) Łac.: comprim*re = ścieśniać, sprężać; compressio = ścieśnianie

Pol.: komprymować; kompresja

Słowa pochodne: dekompresja, kompresor, dekompresor

(W informatyce także: upakowywać, rozpakowywać)

2) Łac.: codex = książka

Ang.: code = kod; symbol kodowy

Terminy pochodne: długość kodu; długość symbolu kodowego

18.1.2.Przedmiot kompresji

1) Teksty (znakowe; numeryczne)

2) Obrazy

3) Obrazy animowane i filmy

4) Dźwięki i filmy dźwiękowe

18.1.3.Cele kompresji

1) Oszczędność pamięci

2) Oszczędność kosztów transmisji

18.1.4.Koszty kompresji

Koszty kompresji i dekompresji

18.1.5.Straty w procesie kompresji

Kompresja bezstratna (ang. lossless)

Kompresja stratna (ang. lossy)

18.2.Kompresja tekstów

18.2.1.Środki kompresji

1) Eliminacja obszarów pustych

2) Eliminacja powtórzeń

3) Kody oszczędzające pamięć

4) Kody o zmiennej długości symbolu

5) Kody specjalne

18.2.2. Kody oszczędzające pamięć

Kody alfanumeryczne siedmiobitowe

Kody alfanumeryczne pięciobitowe

Kody z przesunięciami (ang. shift, np. ICL-1900: przesunięcia trwałe α i β , przesunięcie dla jednego znaku δ )

Kody z przesunięciami A i N („alfabetyczne” i „numeryczne”, np. w pięciobitowym kodzie dalekopisowym długość kodu = (32 - 2) * 2 = 60)

18.2.3.Kody o zmiennej długości symbolu

( = kody Huffmana)

Statystyka częstości występowania znaków

Zakaz prefiksowania się symboli

Statystyczna ocena oszczędności pamięci

18.2.4.Kody specjalne

Kody specjalne jednobajtowe (długość do 256 symboli)

Kody specjalne dwubajtowe (długość do 64K symboli)

18.3.Kompresja obrazów

(wg Levine J.: „Programowanie plików graficznych”, 1994)

18.3.1.Kodowanie obrazu bez kompresji

Palety: 2; 16; 256 kolorów ( = 1; 4; 8 bitów/piksel; „pełne kolory” = 24 b/px)

18.3.2.Kompresja z licznikami powtórzeń

(Levine, str.32, format PackBits)

Zapis obrazu składa się z zapisów dwojakiego rodzaju:

1) Zmiennej długości zapis nie komprymowanego ciągu bajtów:

Jeżeli pierwszy bit pierwszego bajtu zapisu ma wartość 0 (tzn. wartość bajtu p = 0...127), to l = p + 1 odczytuje się jako długość nie komprymowanego ciągu bajtów następujących bezpośrednio po nim.

2) Dwubajtowy zapis komprymowanego ciągu powtarzających się bajtów

Jeżeli pierwszy bit pierwszego bajtu zapisu ma wartość 1 (tzn. wartość bajtu p = 128...255), to r = 257 - p odczytuje się jako licznik długości ciągu powtórzeń bajtu następującego bezpośrednio po nim.

18.3.3.Kompresja słownikowa

(Levine, str.245, format LZW)

Kod słownikowy LZW (Levine, str.34: od nazwisk Lempel, Ziv i Welch) buduje słownik „w locie” podczas czytania danych wejściowych.

Zasady ogólne:

1) Słownik jest ciągiem par (symbol ciągu, ciąg)

2) Do słownika wprowadzane są:

a) ciągi o długości jednego piksela

b) ciągi dłuższe, które w komprymowanym obrazie wystąpiły co najmniej raz, pod warunkiem, że poprzednio wprowadzony został do słownika prefiks główny danego ciągu

3) Ciąg pikseli zapisywany jest w słowniku w postaci pary (symbol prefiksu głównego, ostatni piksel ciągu)

Odszukiwanie ciągu w słowniku: tablica rozproszona

18.3.4.Kompresja JPEG

(Levine, str.408; Joint Photographic Experts Group)

Stratna; przeznaczona do cyfrowo reprezentowanych kolorowych fotografii

Statystyczna średnia współczynnika kompresji: ok. 1 b/px

Etapy:

1) Obliczenie luminancji i chrominancji pikseli:

- zakłada się, że obraz wejściowy zapisany jest w telewizyjnym standardzie RGB (Red, Green, Blue)

- dla każdego piksela oblicza się luminancję Y oraz chrominancję niebieską Cb i czerwoną Cr (liniowe przekształcenie składowych RGB)

- rozdziela się dalszą obróbkę obrazu na obróbkę obrazów częściowych Y, Cb i Cr

- dzieli się obrazy Cb i Cr na bloki o wymiarach 2*2 piksele i uśrednia chrominancje w obrębie każdego z tych bloków (*)

2) Dyskretna transformacja kosinusowa (DCT, Discrete Cosine Transform):

- każdy blok 8*8 elementów obrazu częściowego rozkłada się na składową stałą i 63 harmoniczne przestrzenne

3) Kwantyzacja (**):

- kwantuje się amplitudy harmonicznych, ograniczając pamięć potrzebną do ich zapisu

4) Kompresja końcowa:

- komprymuje się ciągi zer metodą licznikową

- pozostałe zapisy komprymuje się np. metodą Huffmana

Objaśnienie:

(*) Częściowa utrata informacji dotyczącej kolorów

(**) Główny czynnik kompresji, ale także i utraty informacji

18.3.5.Przykład skutków kwantyzacji JPEG

(B.C.Smith, „Multimedia Systems”, 1995, Topic 5)

1) Kompresja 9,6 : 1

2) Kompresja 98 : 1

18.4.Kompresja obrazów ruchomych i dźwięku

18.4.1.Obrazy ruchome wieloplanowe („2,5-wymiarowe”)

W przypadku kilku wzajemnie przesłaniających się planów komprymować każdy plan osobno. W czasie dekompresji uwzględniać priorytety poszczególnych planów.

18.4.2.Standard H.261

(B.C.Smith jw., Topic 5, str.15)

Opracowany w latach 1988 - 1990 przez CCITT (Comit* Consultatif International de T*l*graphie et T*l*phonie, Międzynarodowy Komitet Konsultacyjny dla Telegrafii i Telefonii) z przeznaczeniem dla wideokonferencji i wideotelefonii

W zakresie wizji wykorzystuje:

1) standard JPEG (bloki Y, Cb i Cr , dyskretną transformację kosinusową oraz kwantyzację jej wyników)

2) kodowanie różnicowe

3) predykcję ruchu

18.4.3.Standard MPEG

(B.C.Smith jw., Topic 6, str.9)

Opracowany ok. roku 1990 przez Motion Picture Experts Group z przeznaczeniem dla kom-presji wizji i fonii filmów dźwiękowych

W zakresie fonii:

1) Przekształca zapis na częstotliwościowy, stosując szybką transformację Fouriera (FFT)

2) Rozbija analizowane pasmo na 32 częściowe pasma „krytyczne”

2) Eliminuje pasma charakteryzujące się niską energią

3) Komprymuje zapis, stosując jego kwantyzację

28



Wyszukiwarka

Podobne podstrony:
KOMPLEKSY POLAKOW wykl 29 03 2012
ASD od z Sawanta II Wykład17 6
pytania nowe komplet
zwiazki kompleksowe 2
8 kompleksy
W19 kompleksonometria, wska«niki i krzywe miareczkowania kompleks i
Bliskowschodni kompleks bezpieczeństwa Przyczyny destabilizacji w regionie
Kompleksowa ocena geriatryczna
Komplementarnosc
ASD 2012 test6
Kompleksowa rozgrzewka z pilkam Nieznany
nw asd w13
Kompleksowa rozgrzewka z pilkam Nieznany (2)
ModulIII cz3 kompleksy i osady Nieznany
Metody kompleksowego zarządzania jakością karty kontrolne
dok po wypadku komplet, polec pow
transport zywnosci, Transport Polsl Katowice, 5 semestr, TPD, Komplet
Procedury check in i check out oraz kompleksowa obsługa, powtórki do egzaminów

więcej podobnych podstron