Wstęp do informatyki Wykład 6 (Jones, Konstruowanie
Transkrypt
Wstęp do informatyki Wykład 6 (Jones, Konstruowanie
Wstęp do informatyki Wykład 6 (Jones, Konstruowanie oprogramowania metodą systematyczną, WNT, W-wa 1984) Abstrakcyjne typy danych (zbiory i listy, stos, kolejka) Jeśli jakiś typ danych nie występuje w języku programowania, nazywamy go abstrakcyjnym. Abstrakcyjne typy danych służą m.in. do skracania specyfikacji zadań, projektowania algorytmów, modularyzacji programów. Typ danych jest określony przez: 1. zbiór wartości 2. zbiór wartości oraz odpowiedni zbiór operacji, 3. zestaw operacji (wartości mogą być dowolne). Przyjmujemy, że (abstrakcyjny) typ danych scharakteryzowany jest całkowicie przez zestaw operacji. W programie należy posługiwać się nim wyłącznie za pomocą tych operacji. Oddziela się część „prywatną” typu (czyli szczegóły reprezentacji danych i implementacji poszczególnych operacji) od części „publicznej” (tego, co można wykorzystywać w innych miejscach programu), zwanej interfejsem. Zatem abstrakcja danych jest ukrywaniem szczegółów reprezentacji i implementacji za pomocą możliwie prostych interfejsów. Zbiór (w sensie teorii mnogości) Notacja: {} – zbiór pusty, {a, b, ...} – zbiór o elementach a, b, ... {f(x): p(x)} – zbiór o takich elementach f(x), dla których jest spełniony predykat p(x) Przykłady: {n2: 0<=n<=3}={0,1, 4, 9} Operacje dotyczące zbiorów: x in S – element x należy do zbioru S A + B – suma zbiorów A – B – różnica zbiorów A * B – iloczyn (część wspólna) zbiorów A <= B – A jest podzbiorem B Zbiór – nie jest istotna kolejność elementów i elementy nie powtarzają się. Przykład. Specyfikacja funkcji NWD(x,y) z wykorzystaniem zbiorów NWD: N+ x N+ -> N+ post-NWD(x,y,w): w = max{d: d|x ^ d|y} Przykłady implementacji typu danych zbiór (zob. wykład z Kursu C). Lista Listą liniową nazywamy dowolnie długi ciąg elementów; elementy są ponumerowane i mogą się powtarzać. Notacja (częściowo wzięta z polskiej wersji języka Logo): [ ] – lista pusta, 0 elementów [1,3,1] – lista 3 elementowa Na typy elementów listy nie nakłada się ograniczeń: mogą to być liczby (np. [3,5]), słowa (np. [abc, a12]), listy (np. [[3,4],[ ]], [3,[4,a],z]). Proste, czyli nie będące listami, elementy listy są nazywane atomami (język LISP) lub słowami (język LOGO). Porządek elementów listy jest istotny, np. lista [1,2] jest różna od listy [2,1]. Przykłady implementacji listy liniowej: tablica i lista łączona (lista z dowiązaniami) Operacje (funkcje) na listach analiza listy: pierw(L) – wartością jest pierwszy element z listy L; wartość nieokreślona dla pustej listy L bp(L) – wartością jest lista L bez pierwszego elementu; wartość nieokreślona dla pustej listy L ost(L) – wartością jest ostatni element z listy L; wartość nieokreślona dla pustej listy L bo(L) – wartością jest lista L bez ostatniego elementu; wartość nieokreślona dla pustej listy L konstrukcja listy: lista(a,b) – [a,b] ; wartością jest lista elementów a i b, zd(a*,b*) – [a**, b**] ; jeśli a* (b*) jest atomem, czyli liczbą lub słowem, to a** (b**) jest tym samym atomem; jeśli a* (b*) jest listą, to a** (b**) jest zawartością tej listy po zdjęciu jednej pary zewnętrznych nawiasów. Listy można porównywać tylko operatorem = z listą pustą, np. warunek [1,2]=[ ] jest fałszywy Przykłady: pierw ([[1,2],3,5]) = [1,2] lista([1],[2]) = [[1],[2]] bp([2,5]) = [5] ost ([1,2]) = 2 bo([1,2]) = [1] zd([1],[2]) = [1,2] lista([ ],3) = [[ ],3] zd([ ],3) = [3] Definicje przykładowych funkcji dla list L Wartością funkcji długość(L) jest liczba elementów listy L długość(L) = if L = [ ] then 0 else 1+ długość(bp(L)) Funkcja odwrotna, której wartością jest lista-argument z elementami w odwrotnej kolejności, np. odwrotna ([1,2,3]) = [3,2,1] odwrotna (L) = if L = [ ] then [ ] else zd(ost(L), odwrotna(bo(L))) Ilustracja sposobu obliczania wartości odwrotna([1,2,3]) Abstrakcyjne typy danych – stos (ang. stack, LIFO – Last In First Out) Stos – lista liniowa, do której dostęp jest tylko z jednego końca. Terminologia: szczyt/wierzołek stosu (ang. top), dno/podstawa stosu (ang. bottom). Operacje charakteryzujące stos: 1. Inicjowanie stosu: inicjuj (ang. init). 2. Umieszczanie elementu e na szczycie stosu: wstaw(e) (ang. push). 3. Usunięcie elementu ze szczytu stosu: usun (ang. pop); dla stosu pustego – błąd. 4. Odczytanie elementu ze stosu bez usuwania go: szczyt (ang. top). 5. Sprawdzenie, czy stos jest pusty: czyPusty (ang. isEmpty). Reprezentacja stosu: w tablicy lub w jednokierunkowej liście łączonej. Określenie kolejki (ang. queue) i kolejki podwójnej (ang. double gueue) przez podanie operacji. Reprezentacje tych typów danych w tablicy i za pomocą list łączonych.