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