Informatyka 1 Wykład VIII Rekordy, przeszukiwanie i sortowanie tablic Robert Muszyński ZPCiR ICT PWr Zagadnienia: rekordy, rekordy jako argumenty procedur i funkcji, operacje na plikach z rekordami, przeszukiwanie tablic: liniowe, binarne, sortowanie tablic: przez wstawianie, drzewiaste, bąbelkowe, szybkie, przez scalanie. Copyright c 2001 2003 Robert Muszyński Niniejszy dokument zawiera materiały do wykładu na temat podstaw programowania w językach wysokiego poziomu. Jest on udostępniony pod warunkiem wykorzystania wyłącznie do własnych, prywatnych potrzeb i może być kopiowany wyłącznie w całości, razem ze stroną tytułową. Skład FoilTEX
Rekordy, przeszukiwanie i sortowanie tablic 1 Rekordy rek.pole1 rek.pole2 rek.polen Typ1 Typ2 TypN rek.pole prosta zmienna TYPE LiczbyZespolone = RECORD Re, Im : REAL; VAR X1,X2,Suma,Iloczyn: LiczbyZespolone; (***************************************************) Suma.Re := X1.Re + X2.Re; Suma.Im := X1.Im + X2.Im; Iloczyn.Re := X1.Re * X2.Re - X1.Im * X2.Im; Iloczyn.Im := X1.Re * X2.Im + X1.Im * X2.Re;
Rekordy, przeszukiwanie i sortowanie tablic 2 Posługiwanie się rekordami każde pole musi być podane jawnie kolejność pól w deklaracji jest nieistotna możliwe jest podstawianie całych rekordów zmienne rekordowe mogą być argumentami procedur i funkcji (ale nie wartościami funkcji!!!) zgodność typów rekordy z wariantami
Rekordy, przeszukiwanie i sortowanie tablic 3 Przykłady użycia rekordów TYPE KlasaOkretu= (Barka, Kuter, Tankowiec, Lodolamacz); KlasaNapedu= (Wiosla, Zagle, Para, Diesel, Atomowy); Data = RECORD Rok, Miesiac : INTEGER; Dzien : INTEGER; Okret = RECORD Nazwa : String; Zwodowany, Remont, Wyplynal, Oczekiwany : Data; wmorzu,zaloga : INTEGER; Klasa : KlasaOkretu; Tonaz,Dlugosc : INTEGER; Naped : KlasaNapedu; VAR S1, S2, S3 : Okret; (***************************************************) S1.Nazwa := Moja Zocha ; S1.Klasa := Kuter; S1.Naped := Diesel; S1.Tonaz := 50; S1.Dlugosc := 20; S1.Zaloga := 2; S1.Zwodowany.Rok := 1962; S1.Zwodowany.Miesiac := 4; S1.Zwodowany.Dzien := 1; S1.Wyplynal := S1.Zwodowany; S2 := S1;
Rekordy, przeszukiwanie i sortowanie tablic 4 TYPE Napis = RECORD Tekst : String; Dlugosc : INTEGER; Data = RECORD Rok, Miesiac, Dzien : INTEGER; Osoba = RECORD Imie, Nazwisko, MiejsceUrodzenia : Napis; DataUrodzenia : Data; LiczbaDzieci : INTEGER; ImionaDzieci : ARRAY [1..20] OF Napis; Wyksztalcenie : (brak, podstawowe, srednie, wyzsze); VAR StaryZawislak : Osoba; Kartoteka : ARRAY [1..1000] OF Osoba; (***************************************************) StaryZawislak.Wyksztalcenie := srednie; StaryZawislak.Imie.Tekst := Pawel ; StaryZawislak.Imie.Dlugosc := 5; StaryZawislak.Nazwisko.Tekst := Zawislak ; StaryZawislak.Nazwisko.Dlugosc := Dlugosc(StaryZawislak.Nazwisko.Tekst); StaryZawislak.ImionaDzieci[1].Tekst := Balbina ; {...} Kartoteka[1].Nazwisko.Tekst := Nowak ; Kartoteka[7] := StaryZawislak; Kartoteka[1].DataUrodzenia := Kartoteka[7].DataUrodzenia;
Rekordy, przeszukiwanie i sortowanie tablic 5 FUNCTION RoznicaDat(d1, d2: Data): INTEGER; (* Funkcja oblicza PRZYBLIZONA ilosc dni miedzy datami *) (* d1 a d2 w dniach. Jesli d1>d2 to wynik jest ujemny *) BEGIN RoznicaDat := (d2.rok - d1.rok) * 365 + (d2.miesiac - d1.miesiac) * 30 + (d2.dzien - d1.dzien) (* RoznicaDat *) PROCEDURE PobierzDate(VAR d: Data; s: String); (* Procedura pyta uzytkownika o date wyswietlajac poda-*) (* ne pytanie; wymusza legalna date w latach 1900-2030.*) BEGIN WRITELN( Prosze podac date,s); WITH d DO REPEAT WRITELN( Rok: ); READLN(Rok); UNTIL (Rok >= 1900) AND (Rok <= 2030); WITH d DO REPEAT WRITELN( Miesiac: ); READLN(Miesiac); UNTIL (Miesiac >= 1) AND (Miesiac <= 12); WITH d DO REPEAT WRITELN( Dzien: ); READLN(d.Dzien); UNTIL (Dzien >= 1) AND (Dzien <= 31); {PobierzDate}
Rekordy, przeszukiwanie i sortowanie tablic 6 WITH S1 DO BEGIN PobierzDate(Zwodowany, zwodowania okretu ); PobierzDate(OstatniRemont, ostatniego remontu ); PobierzDate(Wyplynal, wyplyniecia z portu ); PobierzDate(Oczekiwany, oczekiwanego powrotu ); wmorzu := RoznicaDat(Wyplynal,Dzis);
Rekordy, przeszukiwanie i sortowanie tablic 7 Wczytywanie rekordów z pliku PROGRAM rodzina (INPUT,OUTPUT,Dane); CONST Max_Osob = 200; TYPE Osoba = RECORD ImieiNazwisko : String30; PESEL : INTEGER; DataUrodzenia : Data; {...} TabOsob = ARRAY [1..Max_Osob] OF Osoba; VAR NOsoby : INTEGER; Rodzina : TabOsob; Dane : FILE OF Osoba; (***************************************************) RESET(Dane); {pomijamy kwestie nazwy pliku} NOsoby := 0; WHILE (NOT EOF(Dane)) AND (NOsoby < Max_Osob) DO BEGIN NOsoby := NOsoby + 1; READ(Dane,Rodzina[NOsoby]); {WRITE(...) przy REWRITE} {...} END.
Rekordy, przeszukiwanie i sortowanie tablic 8 Przeszukiwanie tablic liniowe Poszukiwanie wzorca wœród elementów tablicy jednowymiarowej od elementu min do max Tab[min] = wzorzec lub min = max? min = min + 1 binarne Poszukiwanie wzorca wœród elementów tablicy jednowymiarowej od elementu min do max Srodek = (min + max) div 2 max = Srodek - 1 min = Srodek + 1 Tab[Srodek] = wzorzec lub min=max? Tab[Srodek] < wzorzec?
Rekordy, przeszukiwanie i sortowanie tablic 9 Przeszukiwanie liniowe CONST MaxWartosci = 30; TYPE Wartosci = ARRAY[1..MaxWartosci] OF INTEGER; FUNCTION Przeszukaj(tab: Wartosci; Klucz: INTEGER; min,max,domysl:integer):integer; (* Wyszukuje wartosc Klucz w tablicy *) (* pomiedzy indeksami min i max *) (* Zwraca jej index lub domysl gdy nie znaleziona *) VAR znaleziony: BOOLEAN; Przeszukiwanie binarne (*... POSORTOWANEJ *) BEGIN znaleziony := FALSE; WHILE ((NOT znaleziony) AND (min <= max)) DO BEGIN IF Porownanie(tab[min],Klucz) THEN znaleziony := TRUE ELSE min := min + 1 IF znaleziony THEN Przeszukaj := min ELSE Przeszukaj := domysl { Przeszukaj } srodek := (min + max) div 2; CASE Porownanie(tab[srodek],Klucz) OF 0: znaleziony := TRUE -1: max := srodek - 1 1: min := srodek + 1 END
Rekordy, przeszukiwanie i sortowanie tablic 10 przez wstawianie Sortowanie przez proste wstawianie przez wstawianie połówkowe przez wybieranie drzewiaste przez zamianę bąbelkowe szybkie przez scalanie
Rekordy, przeszukiwanie i sortowanie tablic 11 Sortowanie przez proste wstawianie Sortowanie tablicy przez wstawianie j = 2 temp = Tab[j] i = j - 1 Wstaw Tab[j] w posortowany ci¹g Tab[1..j-1] 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 Tab[i] > temp i i > 0? Tab[i+1] = temp Czy element j-ty jest ostatni? Tab[i+1] = Tab[i] i = i - 1 j = j + 1
Rekordy, przeszukiwanie i sortowanie tablic 12 Sortowanie drzewiaste Przekszta³æ tablicê w drzewo binarne Sortowanie tablicy drzewiaste krok I 5 2 4 6 1 3 5 ObejdŸ drzewo w porz¹dku "najpierw w lewo" i wypisz ka dy element przy okazji drugich jego odwiedzin 1 2 4 6 3 krok II 5 2 1 1 1 2 4 3 3 3 4 4 2 5 6 6 6 5
Rekordy, przeszukiwanie i sortowanie tablic 13 Sortowanie bąbelkowe Sortowanie tablicy b¹belkowe j = 1 i = 1 5 2 4 6 1 3 Tab[i] > Tab[i+1]? Zamieñ Tab[i] z Tab[i+1] 2 4 5 1 3 6 2 4 1 3 5 6 i = i + 1 2 1 3 4 5 6 Czy element i-ty jest przedostatni? 1 2 3 4 5 6 1 2 3 4 5 6 j < n - 1? j = j + 1
Rekordy, przeszukiwanie i sortowanie tablic 14 Sortowanie bąbelkowe Sortowanie tablicy b¹belkowe j = 1 i = 1 Tab[i] > Tab[i+1]? i = i + 1 Czy element i-ty jest przedostatni? j < n - 1? Zamieñ Tab[i] z Tab[i+1] j = j + 1 PROCEDURE BubbleSort(VAR Tab : Wartosci; min, max : INTEGER); VAR i, j: INTEGER; BEGIN FOR j := min TO (max - 1) DO FOR i := min TO (max - 1) DO IF Tab[i] > Tab[i+1] THEN Zamien(Tab[i], Tab[i+1]) { BubbleSort }
Rekordy, przeszukiwanie i sortowanie tablic 15 Sortowanie szybkie Sortuj (l, p) i = l j = p x = Tab[(i + j) div 2] Szybkie sortowanie elementów l..p tablicy Sortuj (1, n) Sortowanie tablicy szybkie Tab[i] < x? i = i + 1 Tab[j] > x? j = j - 1 l p 5 2 4 6 7 8 1 3 i <= j? l < j? Zamieñ Tab[i] z Tab[j] i = i + 1; j = j - 1 Sortuj (l, j) 5 j i 2 4 3 1 8 7 6 i < p? Sortuj (i, p) 1 2 3 4 5 6 7 8
Rekordy, przeszukiwanie i sortowanie tablic 16 Sortowanie przez scalanie 5 2 4 6 7 8 1 3 podzial Podziel tablicê na dwie czêœci Sortowanie tablicy przez scalanie 5 2 4 6 7 8 1 3 podzial podzial 5 2 4 6 7 8 1 3 Posortuj otrzymane tablice u ywaj¹c rekurencyjnie sortowania przez scalanie............ Po³¹cz postortowane tablice w posortowan¹ tablicê 2 5 4 6 7 8 1 3 5 scalenie 2 4 6 8 7 scalenie 3 1 2 4 5 6 1 3 7 8 rekurencyjne wywo³anie sortowania przez scalanie 6 5 4 scalenie 2 1 3 7 8 1 2 3 4 5 6 7 8