You are on page 1of 16

Techniki programowania 2018-02-22

Techniki programowania
Wprowadzenie do zadania 1

1. Reprezentacje struktur grafowych

2. Zasada dziel i zwyciężaj i jej zastosowania

3. Wybrane algorytmy grafowe

Graf

G = ( V, E )

V - zbiór wierzchołków, E - zbiór krawędzi

dr inż. Piotr Borowiecki, KAMS WETI PG 1


Techniki programowania 2018-02-22

Digraf

D = ( V, A )

V - zbiór wierzchołków, A - zbiór łuków

Różne grafy

dr inż. Piotr Borowiecki, KAMS WETI PG 2


Techniki programowania 2018-02-22

Modelowanie grafowe

Sieci społecznościowe

dr inż. Piotr Borowiecki, KAMS WETI PG 3


Techniki programowania 2018-02-22

Reprezentacje grafów

- macierz sąsiedztwa wierzchołków


- macierz incydencji
- listy sąsiedztwa
- wersja dynamiczna i jej warianty,
- wersja tablicowa.
- reprezentacje specjalizowane np.
dla drzew binarnych, 1 2

4 3

Macierz sąsiedztwa wierzchołków grafu


Macierz sąsiedztwa wierzchołków grafu jest macierzą o wartościach w zbiorze {0,1}

G[i,j] == 1, gdy wierzchołki o numerach i+1 oraz j+1 są sąsiednie,


G[i,j] == 0, w przeciwnym przypadku.

0 1 2 3 4 5
6
0 0 1 1 1 0 0

1 1 0 1 0 1 0 3
2 1 1 0 0 0 1

3 1 0 0 0 0 0
1 2
4 0 1 0 0 0 0
4 5
5 0 0 1 0 0 0

dr inż. Piotr Borowiecki, KAMS WETI PG 4


Techniki programowania 2018-02-22

Listy sąsiedztwa wierzchołków grafu

0 2 3 4
NULL
1
2 1 4

3 NULL

1
NULL

1 2 1 2
NULL

4 3

Dynamiczna reprezentacja drzewa binarnego

10
root
10

7 12 7 12

42 4 1 30

1
15 20 5

8
15
NULL NULL
Drzewo binarne (BT – ang. binary tree) ...

... i jego reprezentacja.


10

dr inż. Piotr Borowiecki, KAMS WETI PG 5


Techniki programowania 2018-02-22

Zasada "dziel i zwyciężaj"

Zasada dziel i zwyciężaj polega na podzieleniu danych reprezentujących


instancję pewnego problemu na dwie lub więcej instancji (podproblemów)
o tej samej postaci co instancja problemu pierwotnego, lecz o mniejszych
rozmiarach i dalszym dzieleniu otrzymanych tak instancji zgodnie z tą samą
zasadą, tak długo, aż rozmiar otrzymanych przez podział instancji pozwoli na
ich szybkie rozwiązanie reprezentowanego przez nie podproblemu.

Jeżeli rozwiązanie jednego z podproblemów nie stanowi rozwiązania problemu


pierwotnego to rozwiązania podproblemów należy scalić.

11

Zasada "dziel i zwyciężaj"


(wybrane zastosowania)

poszukiwanie binarne

sortowanie przez scalanie


rys. D. Harel, Rzecz o istocie informatyki - Algorytmika

12

dr inż. Piotr Borowiecki, KAMS WETI PG 6


Techniki programowania 2018-02-22

Poszukiwanie binarne
(implementacja dla tablicy jednowymiarowej)

typedef int elem;


const int MAX_N = 50;
int main ()
{
elem A[MAX_N];
elem szukany;
int n;
int gdzie;
...
cout << "Czego szukamy? :";
cin >> szukany;
if ((gdzie = BinSearch(szukany,A,0,n-1)) != -1)
cout << "znaleziono " << szukany
<< " pod indeksem " << gdzie << endl;
else cout << " nie znaleziono elementu " << szukany << endl;
...
}

13

Poszukiwanie binarne
(implementacja rekurencyjna dla tablicy jednowymiarowej)

int BinSearch(elem szukany, elem *A, int lewy, int prawy)


{
int mid;
if (lewy > prawy) return(-1) ;
else {
mid = (lewy + prawy)/2;
if (A[mid] == szukany) return(mid);
else {
if (szukany < A[mid])
return(BinSearch(szukany, A, lewy, mid - 1));
else return(BinSearch(szukany, A, mid + 1, prawy));
}
}
}

14

dr inż. Piotr Borowiecki, KAMS WETI PG 7


Techniki programowania 2018-02-22

Poszukiwanie binarne
(implementacja nierekurencyjna dla tablicy jednowymiarowej)

int BinSearch(elem szukany, elem *A, int lewy, int prawy)


{
int mid;
while (lewy <= prawy) {
mid = (lewy + prawy)/2;
if (A[mid] == szukany) return mid;
else
if (szukany < A[mid]) prawy = mid - 1;
else lewy = mid + 1;
}
return -1;
}

W tym przypadku wyeliminowanie rekurencji jest łatwe.


15

Drzewo poszukiwań binarnych

10
Drzewo poszukiwań binarnych zbudowane
jest w taki spsób aby dla każdego węzła w
3 23 wartości zapisane w węzłach znajdujących
się w jego lewym poddrzewie były mniejsze
od wartosci w węźle w, a w prawym nie
1 4 17 30 mniejsze od wartości w węźle w.

15 20 35

18

Drzewo poszukiwań binarnych


(BST – binary search tree)

16

dr inż. Piotr Borowiecki, KAMS WETI PG 8


Techniki programowania 2018-02-22

Drzewo poszukiwań binarnych

Rozważmy poszukiwanie elementu o


10 wartości 21

3 23 10 < 21 => Prawe poddrzewo

23 > 21 => Lewe poddrzewo


1 4 17 30
17 < 21 => Prawe poddrzewo

15 20 35 20 < 21 => Prawe poddrzewo

Prawe poddrzewo o korzeniu w 20


18 jest puste
=>
W drzewie nie ma elementu
Drzewo poszukiwań binarnych o wartości 21
(BST – binary search tree)

17

Dynamiczna reprezentacja drzewa binarnego

10 10
root
3 23

3 23
1 4 17 30

15 20 35
17

18

struct wezel { 15
int value;
NULL NULL
wezel *right;
wezel *left;
};
18

dr inż. Piotr Borowiecki, KAMS WETI PG 9


Techniki programowania 2018-02-22

Umieszczanie binarne
(tworzenie drzewa binarnych poszukiwań)

// Umieszczanie binarne
// ------------------------------------------------------------
struct wezel {
int value;
wezel *right;
wezel *left;
};
int main(void)
{
int wstawiany;
wezel *root = NULL;
int i = 1;
cout << "w" << i++ << ": ";
cin >> wstawiany;
while (wstawiany != 0){
BST_insert(root,wstawiany);
cout << "w" << i++ << ": ";
cin >> wstawiany;
}
...
} 19

Umieszczanie binarne
(tworzenie drzewa binarnych poszukiwań)

// Umieszczanie binarne
// ------------------------------------------------------------

void BST_insert(wezel *&r, int x)


{
if (r == NULL)
{
wezel *nowy = new wezel;
nowy->value = x;
nowy->right = NULL;
nowy->left = NULL;
r = nowy; // dowiązanie nowego węzła
// do węzła "wyższego poziomu"
}
else if (x >= r->value) BST_insert(r->right,x);
else BST_insert(r->left,x);
}

20

dr inż. Piotr Borowiecki, KAMS WETI PG 10


Techniki programowania 2018-02-22

Poszukiwanie binarne

// Poszukiwanie binarne elementu o zadanej wartosci


// -------------------------------------------------

wezel* BST_search(wezel *r, int x)


{
if ((r == NULL) or (r->value == x))
return r;
else
if (x < r->value)
return BST_search(r->left,x);
else
return BST_search(r->right,x);
}

21

Drzewo binarnych poszukiwań


(element największy i najmniejszy)

// Wyznaczanie elementu najwiekszego i najmniejszego


// -------------------------------------------------

wezel* BST_max(wezel *r)


{
if ((r != NULL) and (r->right != NULL))
return BST_max(r->right);
else return r;
}

wezel* BST_min(wezel *r)


{
if ((r != NULL) and (r->left != NULL))
return BST_min(r->left);
else return r;
}

22

dr inż. Piotr Borowiecki, KAMS WETI PG 11


Techniki programowania 2018-02-22

Przeszukiwanie drzewa binarnego


(uwaga to nie musi być BST)
// Przeszukiwanie drzewa binarnego
// (porządek poprzeczny - inorder)
// -------------------------------------------------

void BT_inorder(wezel *r)


{
if (r != NULL) { 10
BT_inorder(r->left);
cout << r->value;
BT_inorder(r->right); 3 23
}
}
1 4 17 30

15 20 35
Odwiedzanie są wszystkie węzły
w kolejności:
18
1 3 4 10 15 17 18 20 23 30 35
23

Przeszukiwanie drzewa binarnego


(uwaga to nie musi być BST)
// Przeszukiwanie drzewa binarnego
// (porządek wzdłużny - preorder)
// -------------------------------------------------

void BT_preorder(wezel *r)


{
if (r != NULL) {
cout << r->value; 10
BT_preorder(r->left);
BT_preorder(r->right);
} 3 23
}

1 4 17 30

15 20 35
Odwiedzanie są wszystkie węzły
w kolejności:
18
10 3 1 4 23 17 15 20 18 30 35
24

dr inż. Piotr Borowiecki, KAMS WETI PG 12


Techniki programowania 2018-02-22

Przeszukiwanie drzewa binarnego


(uwaga to nie musi być BST)
// Przeszukiwanie drzewa binarnego
// (porządek wsteczny - postorder)
// -------------------------------------------------

void BT_postorder(wezel *r)


{
if (r != NULL) {
BT_postorder(r->left); 10
BT_postorder(r->right);
cout << r->value;
} 3 23
}

1 4 17 30

15 20 35
Odwiedzanie są wszystkie węzły
w kolejności:
18
1 4 3 15 18 20 17 35 30 23 10
25

Przeszukiwanie grafu
Przeszukiwanie grafu wgłąb - algorytm DFS (ang. Depth First Search)

6
6
3
3

1 2
1 2
4 5
4 5

6
stos

3 3 3 5
2 2 2 2 2 2 2 4
1 1 1 1 1 1 1 1 1 1 1

czas 26

dr inż. Piotr Borowiecki, KAMS WETI PG 13


Techniki programowania 2018-02-22

Przeszukiwanie grafu
Przeszukiwanie grafu wgłąb - algorytm DFS (ang. Depth First Search)

1 2

4 5

6
stos

3 3 3 5
2 2 2 2 2 2 2 4
1 1 1 1 1 1 1 1 1 1 1

czas 27

Przeszukiwanie grafu
Przeszukiwanie grafu wgłąb - algorytm DFS (ang. Depth First Search)

1 2

4 5

6
stos

3 3 3 5
2 2 2 2 2 2 2 4
1 1 1 1 1 1 1 1 1 1 1

czas 28

dr inż. Piotr Borowiecki, KAMS WETI PG 14


Techniki programowania 2018-02-22

Przeszukiwanie grafu (implementacja algorytmu DFS)


void ReadGraph (int[][MAX_N], int&);
void DFS (int[][MAX_N], bool[], int, int);
void Init (int[MAX_N][MAX_N], bool[MAX_N]);

int main(void)
{
int G[MAX_N][MAX_N]; // macierz sasiedztw wierzchołków
bool Visited[MAX_N]; // znaczniki odwiedzenia wierzchołków
int n;
int v;

Init(G,Visited);
ReadGraph(G,n);

cout << "Startowy: ";


cin >> v;
v--;

DFS(G,Visited,n,v);

...
}
29

Przeszukiwanie grafu
Implementacja c.d.

void Init (int G[MAX_N][MAX_N], bool Visited[MAX_N])


{
for (int i=0; i<MAX_N; i++)
{
for (int j=0; j<MAX_N; j++)
G[i][j] = 0;

Visited[i] = false;
}
}

30

dr inż. Piotr Borowiecki, KAMS WETI PG 15


Techniki programowania 2018-02-22

Przeszukiwanie grafu
Implementacja c.d.
void ReadGraph (int G[][MAX_N], int& n)
{
int u,v;
cout << "Podaj liczbe wierzcholkow ";
cin >> n;
if (n>0) {
cout << ":"; cin >> u; // Podanie 0 dla u lub v konczy wpisywanie
if (u!=0) {
cout << ":"; cin >> v;
cout << endl;
}
while((u!=0) and (v!=0)){
G[u-1][v-1] = 1;
G[v-1][u-1] = 1;
cout << ":"; cin >> u;
if (u!=0) {
cout << ":";
cin >> v;
cout << endl;
}
}
} 31
}

Przeszukiwanie grafu
Implementacja c.d.

void DFS (int G[][MAX_N], bool Visited[], int n, int v)


{
int u;
Visited[v] = true;
for (u=0; u<n; u++)
if ((G[v][u] == 1) and not Visited[u])
{
cout << setw(3) << v+1 << "-->"
<< setw(3) << u+1 << endl;

DFS(G,Visited,n,u);

cout << setw(3) << v+1 << "<--"


<< setw(3) << u+1 << endl;
}
}

32

dr inż. Piotr Borowiecki, KAMS WETI PG 16

You might also like