dydaktyka

Algorytmy i struktury danych

Grzegorz Bancerek
WSFiZ Ełk, II rok, III semestr, informatyka, 2006, studia niestacjonarne


Slajdy do wykładu, logowanie do testów i wyników, zjazd: I(16.09.2006), II(23.09.2006), III(07.09.2006), IV(21.09.2006), V(04.11.2006), VI(25.11.2006), VII(09.12.2006), VIII(20.01.2007), IX(03.02.2007).
Egzamin: 10:00, sobota 10.02.2007
Zaliczenia: 14:00-16:00, sobota 10.02.2007
Zasady zaliczenia laboratorium: Na każdych zajęciach podawany jest problem do sprogramowania. Za poprawne sprogramowanie problemu w czasie zajęć można uzyskać 2 punkty. Za oddanie i obronienie (należy odpowiedzieć na prę pytań) programu na następnych zajęciach otrzymuje się 1 punkt. Na ostatnich zajęciach punkty są przeliczane na oceny według tabeli:
punktyocena
0-2.9992
3-4.9993
5-6.9993+
7-8.9994
9-11.9994+
12-5

  1. 16.09.2006
    Wykład: Poprawność i złożoność algorytmu, rzędy wielkości funkcji
    Laboratorium: Porównanie trzech metod obliczania potęgi (patrz slady z wykładu 1.1-1.3). Należy dla każdej metody obliczyć ilość wykonanych mnożeń oraz podać czas działania (przykład oblicznia czasu działania: czas.pas). Żeby czas był miarodajny należy obliczenia wykonać odpowiednio dużą ilość razy (np. 30000).
  2. 23.09.2006
    Wykład: Hierarchia wielkości funkcji. Algorytmy obliczania symbolu Newtona - metoda dynamiczna
    Laboratorium: Porównanie metod obliczania symbolu Newtona (patrz slady z wykładu): Należy dla każdej metody obliczyć ilość wykonanych mnożeń (metody 1-4) lub dodawań (metody 5-7) oraz podać czas działania (przykład oblicznia czasu działania: czas.pas). Żeby czas był miarodajny należy obliczenia wykonać odpowiednio dużą ilość razy (np. 30000).
  3. 07.10.2006
    Wykład: Metody sortowania: wybieranie, wstawianie, bąbelkowe, Shella
    Laboratorium: Porównanie 2 metod sortowania
  4. 21.10.2006
    Wykład: Listy, kolejki, stosy
    Laboratorium: Implementacja kolejki jako dwóch stosów:
    Stos należy zaimplementować jako listę liniową jednokierunkową a kolejkę jako rekord zawierający dwa stosy: jeden do wkładania elementów a drugi do pobierania. Jesli pobieramy pierwszy element z kolejki a stos do pobierania jest pusty, to wszystkie elementy ze stosu do wkładania są przerzucane na stos do pobierania i wtedy pobieramy element. Podobnie w przypadku operacji POP.
    type
      Lista = ^Element;
      Element = record
        liczba: integer;
        nast: Lista;
      end;
      Stos = Lista;
    
      function Pusty(S: Stos): boolean;
      function NaGorze(S: Stos): integer;
      procedure Push(var S: Stos; a: integer);
        { należy utworzyć nowy Element
          new(e)
          i przypisać
          e^.liczba := a
          i potem wstawić Element e na górze stosu (na początku listy)
        }
      procedure PopS(var S: Stos);
    
      procedure Przerzuc(var Sin, Sout: Stos); {przerzucanie elementów ze stosu Sin do Sout}
    
    type
      Kolejka = record
        stos_in, stos_out: Stos;
      end;
    
      function Pusta(K: Kolejka): boolean; {czy oba stosy są puste}
      function Pierwszy(K: Kolejka): integer;
        {podaje liczbę w pierwszym elemencie stos_out przerzucając wcześniej
         elementy ze stos_in jeśli trzeba}
      procedure Dodaj(var K: Kolejka; a: integer); {robi Push do stos_in}
      procedure PopK(var K: Kolejka);
        {usuwa pierwszy element ze stos_out przerzucając wcześniej
         elementy ze stos_in jeśli trzeba}
      
    

  5. 04.11.2006
    Wykład: Sortowanie przez scalenie i szybkie.
    Laboratorium: Zaimplementować sortowanie przez scalanie przy użyciu kolejek. Należy użyć jednostki LISTY (uses LISTY), której interfejs wyglada tak
    unit Listy;
    
    interface
    
    type
     Lista = ^Element;
     Element = record .... end;
     Kolejka = record ....
       Count: word; {ilość elemetów w kolejce}
     end;
    
     procedure Init(var K: Kolejka);
     function Pusta(K: Kolejka): boolean;
     function Pierwszy(K: Kolejka): real;
     procedure Inject(var K: Kolejka; x: real);
     procedure Pop(var K: Kolejka);
    
    
    Należy zaimplementować procedury:
    procedure Dziel(var K,K1,K2: Kolejka);
    begin
    { Dzieli kolejkę K na dwie części, które zapisuje do K1 i K2}
    end;
    procedure Scal(var K1,K2,K: Kolejka);
    begin
    { scala posortowane kolejki K1 i K2 w pustą kolejkę K }
    end;
    procedure SortowaniePrzezScalanie(var K: Kolejka);
    var K1,K2: Kolejka;
    begin
      Init(K1);
      Init(K2);
      if K.Count > 1 then
      begin
        Dziel(K,K1,K2);
        SortowaniePrzezScalanie(K1);
        SortowaniePrzezScalanie(K2);
        Scal(K1,K2,K);
      end;
      
    end;
    
    var K: Kolejka;
    
    begin
    { Wczytanie z pliku 'dane.txt' liczb do sortowanie do kolejki K }
      SortowaniePrzezScalanie(K);
    { Wypisanie kolejki K }
    end.
    

  6. 25.11.2006
    Wykład: Sortowanie przez kopcowanie, sortowanie przez wstawianie połówkowe, sortowanie leksykograficzne (pozycyjne).
    Laboratorium: Implementacja sortowania leksykograficznego przy użyciu kolejek.
  7. 09.12.2006
    Wykład: Drzewa binarnego wyszukiwania (BST)
    Laboratorium: Implementacja operacji na drzewach BST.
  8. 20.01.2007 Wykład: UNION-FIND
    Laboratorium: Porównanie implementacji algorytmu UNION-FIND.
    {listowa}
      var Zbior: array[1..n] of 1..n;
      var Pierwszy: array[1..n] of 0..n; (* 0 - brak elementow we zbiorze *)
      var Nastepny: array[1..n] of 0..n; (* 0 - brak nastepnego elementu *)
    
      procedure Init1;
           (* Zbior[i]:=i, Pierwszy[i]:=i, Nastepny[i]:=0 *)
      function FIND1(i: integer): integer;
           (* zbior, do ktorego nalezy element i *)
           (* tzn. Zbior[i] *)
      procedure UNION1(i,j: integer);
           (* zakladamy, ze i <> j; dolaczamy zbior j do i *)
    
    {drzewiasta}
      var Ojciec: array[1..n] of 0..n;  (* 0 - brak ojca *)
      var Ilosc: array[1..n] of 1..n; (* ilosc reprezentowanych elementow *)
    
      procedure Init2; (* wpisuje zera do Ojciec i jedynki do Ilosc *)
      function FIND2(i: integer): integer;
           (* rekurencyjnie znajduje reprezentanta elementu i *)
           (* uzywajac tablicy Ojciec *)
      procedure UNION2(i,j: integer);  (* zakladamy, ze i <> j oraz i i j nie maja ojcow *)
                                      (* laczymy zbiory reprezentowane przez i i j *)
    

  9. 03.02.2007 Wykład: Grafy, tablica list incydencji , przeglądanie grafu wszerz i w głąb. Algorytm Kruskala (użycie UNION-FIND)
    Laboratorium: Implementacja algorytmu Kruskala.
    {UNION-FIND}
    
    {KRUSKAL}
      var Wedges: array[1..m] of record
            start, koniec, waga: integer;
          end;
      ReadGraph; { wczytuje z pliku m krawedzi (trojek liczb) }
      SortWedges; { sortuje krawedzie wg wag }
      Init_UNION_FIND;
      for i:=1 to m do
      begin
        p:=FIND(Wedges[i].start);
        k:=FIND(Wedges[i].koniec);
        if p <> k then
        begin
          { wypisz krawedz }
          UNION(p,k);
        end;
      end;
    


Grzegorz Bancerek