ASD 04
Transkrypt
ASD 04
Algorytmy i Struktury Danych Wykład IV Sortowania cd. Elementarne struktury danych 1 ASD 04 Co dziś? Dolna granica sortowań Mediany i statystyki pozycyjne Warstwa implementacji Warstwa abstrakcji # tablice # listy # stos, kolejki 2 ASD 04 Drzewo decyzyjne ≤ A[1]:A[2] A[2]:A[3] {1,2,3} A[1]:A[3] A[1]:A[3] {1,3,2} > {2,1,3} {3,1,2} ASD 04 A[2]:A[3] {2,3,1} {3,2,1} 3 1 Minimum i maksimum min lub max - liniowe przeszukanie O(n) # n-1 porównań min i max – linowe przeszukanie O(n) # 2n-2 porównań # 3(n/2) - porówań ASD 04 4 Wybór i’tego elementu Algorytm Hoare’a # oczekiwany czas liniowy Algorytm „magicznych piątek” # pesymistyczny czas liniowy 1. podziel n elementów na zbiory 5 elementowe 2. wyznacz medianę z każdej piątki 3. wywołaj rekurencyjnie dla znalezienia mediany median 4. podziel tablicę względem znalezionej mediany 5. wywołaj rekurencyjnie dla mniejszych lub większych elementów ASD 04 5 Warstwa implementacji Możliwości # tablica # wskaźniki (odsyłacze, pointery) # obiekty (referencje) Deklaracje # statyczne # dynamiczne Różnice # szybkość # rodzaje pamięci # moment alokacji ASD 04 6 2 Tablica Tablica statyczna Tablica dynamiczna # realokacja Złożoność # O(1) <-> O(n) Indeks to liczby całkowite -> arytmetyka na pointerach + rzutowanie Ograniczenia # deklaracja # dostępna pamięć ASD 04 7 int tabA[10]; int * tabB = (int*)malloc( 10 * sizeof (int) ); int * tabC = new int[10]; tabB = (int*)realloc( tabB, 20 * sizeof (int) ); tabA[0] = *(tabA + 0); free( tabB ); delete []tabC; Wskaźniki Lista (łańcuch odsyłaczowy) # # # # # jednokierunkowa dwukierunkowa cykliczna z wartownikami drzewa… Złożoność # listy O(1) <-> O(n) # drzewa O(1) <-> O(log(n)) <-> O(n) Ograniczenia # dostępna pamięć ASD 04 9 3 Wskaźniki ASD 04 10 Wskaźniki ASD 04 11 Wskaźniki - wartownik ASD 04 12 4 void void void pEle foo( pEle * head ) ... foo( pEle ** head ) ... foo( pEle *& head ) * foo( pEle * head ) ... // tail, root void foo( pEle * firstele ) ... while( ele ) ... while( ele->next ) ... if ( ele && ele->key == ??? while ( ele && ele->key == ??? if ( ele && ele->next ... Drzewa ASD 04 14 bool foo( pNode * node ) { if ( node->key == ??? if ( node->left ) return foo( node->left ); if ( node->right ) return foo( node->right ); } { if ( i if ( i node->left ) = foo( node->left ); node->right ) += foo( node->right ); } 5 Drzewo? ASD 04 16 Drzewo? ASD 04 17 Inne ASD 04 18 6 Inne ASD 04 19 Inne ASD 04 20 Warstwa abstrakcji Abstrakcyjne struktury danych Implementacja struktury # tablica lub wskaźniki # dodatkowe elementy indeks maksymalny, indeks bieżący… głowa listy, ogon, element wyróżniony … Interfejs struktury # metody, funkcje, operatory # zachowanie ASD 04 21 7 Warstwa abstrakcji Rodzaje metod # zapytania # operacje modyfikujące Dane i klucz Rozpatrywanie złożoności dopiero przy implementacji Implementacja jednaj struktury przy pomocy zaimplementowanego interfejsu innej struktury # kolejka priorytetowa -> kopiec -> tablica ASD 04 22 Metody uniwersalne # search( key ), search( x ) # insert( x ) # delete( x ) # min() # max() # successor( x ) # predecessor( x ) ASD 04 23 Tablica Metody # set # get # size Zachowanie # bezpośredni dostęp do każdego elementu, określona długość(?) Implementacja # tablica # lista jedno (dwu) kierunkowa ASD 04 24 8 Lista jednokierunkowa Metody # # # # # insert search delete isEmpty next Zachowanie # podstawowa cecha to brak ograniczenia na ilość elementów Implementacja # tablica # lista jednokierunkowa 25 ASD 04 Lista 0 1 2 3 4 5 6 7 next 2 * 1 4 key 34 22 12 56 prev 4 7 * 7 6 34 * 1 12 22 3 * 12 6 ASD 04 26 Stos (LIFO) Metody # push # pop # isEmpty Zachowanie # element ostatnio położony jest pierwszy ściągany, kładziemy elementy na wierzchołek stosu i z niego ściągamy Implementacja # tablica # lista jednokierunkowa ASD 04 27 9 Kolejka (FIFO) Metody # isEmpty # put (insert) # get (extract) Zachowanie # element ostatnio położony musi czekać na swoją kolej, pobieramy elementy z początku, a wstawiamy na koniec Implementacja # tablica # lista jednokierunkowa, dwukierunkowa ASD 04 28 Kolejka dwukierunkowa (talia) Metody # isEmpty # putfirst, -last (insert, head-tail) # getfirs, -last (extract, head-tail) Zachowanie # wstawiamy na początek i na koniec, pobieramy elementy z początku lub z końca Implementacja # tablica # lista jednokierunkowa, dwukierunkowa ASD 04 29 Zbiór Metody # # # # add delete isIn union Zachowanie # wszystkie elementy są różne, każdy element występuje jedne raz Implementacja # tablica # lista ASD 05 30 10 Zbiory rozłączne Metody # makeSet # union # findSet Zachowanie # zbiór jest reprezentowany przez reprezentanta, reprezentantem jest korzeń, element zbioru wskazuje na swojego ojca Implementacja # prosta implementacja odsyłaczowa # drzewa ukorzenione # drzewa ukorzenione + Heurystyki łączenie wg rangi kompresja ścieżki ASD 05 31 MakeSet(X x) { x.parent = x; x.rank = 0; } Union(X x,X y) { Link( FindSet(x), FindSet(y) ); } Link(x,y) { if (x.rank > y.rank) y.parent = x; else x.parent = y; if (x.rank == y.rank ) y.rank++; } X FindSet( X x ) { if ( x.parent != x ) x.parent = FindSet(x.parent); return x.parent; } Kolejka priorytetowa Metody # put (insert) # get (extract) # isEmpty Zachowanie # element wstawiamy nie na koniec, ale w zależności od key Implementacja # lista O(n) # tablica posortowana O(n) # kopiec O(log(n)) ASD 05 33 11 void heap(int i) { int l = 2 * i + 1; int r = 2 * i + 2; int maxi,t; if ( l < max && A[l] > A[i] ) // MAX maxi = l; else maxi = i; if ( r < max && A[r] > A[maxi] ) maxi = r; if ( maxi != i ) { t = A[i]; A[i] = A[maxi]; A[maxi] = t; heap( maxi ); } } void heap(int i) { while(1) { int l = 2 * i + 1; int r = 2 * i + 2; int maxi,t; if ( l < max && A[l] > A[i] ) maxi = l; else maxi = i; if ( r < max && A[r] > A[maxi] ) maxi = r; if ( maxi != i ) { t = A[i]; A[i] = A[maxi]; A[maxi] = t; i = maxi; } else break; } } int put( int ele ) { if ( max + 1 == MAX ) // == return error; // ??? int i = max++; while( i > 0 && A[(i-1)/2] < ele ) { A[i] = A[(i-1)/2]; i = (i-1)/2; } A[i] = ele; } 12 class Heap { protected: data* A; int max; public: data get(); void put(data a); Heap(); ~Heap(); } data Heap::get() { if ( max == 0 ) // return error; ??? throw errorHeapEmptyException; data ret = A[0]; A[0] = A[--max]; heap( 0 ); return data; } Jeszcze o kopcu Kopiec binarny Kopiec rzędu d # d-arny # zamiast 2 synów, każdy węzeł ma ich d Złożoność „struktury” # O( log(n)) == O( logd(n)) # szybkość vs łatwość implementacji ASD 05 39 13 Pytania? KONIEC ASD 04 40 14