A 4 B 33 ALG 201004 ALG 04
A 4 B 33 ALG 2010/04 ALG 04 VYHLEDÁVÁNÍ (jednorozměrné vyhledávání) Vyhledávání v poli naivní, binární, interpolační Binární vyhledávací strom (BVS) operace Find, Insert, Delete 0
A 4 B 33 ALG 2010/04 Hledání v seřazeném poli — lineární, POMALÉ Dané pole Seřazené pole: Velikost = N 363 369 388 603 638 693 803 836 839 860 863 938 939 966 968 983 993 najdi 993 ! Testů: N 363 369 388 603 638 693 803 836 839 860 863 938 939 966 968 983 993 najdi 363 ! Testů: 1 363 369 388 603 638 693 803 836 839 860 863 938 939 966 968 983 993 1
A 4 B 33 ALG 2010/04 Hledání v seřazeném poli — binární, RYCHLEJŠÍ najdi 863 ! 2 testy 363 369 388 603 638 693 803 836 839 860 863 938 939 966 968 983 993 369 388 603 638 693 803 839 860 863 938 939 966 968 983 993 2 testy 839 860 863 938 939 966 968 983 993 839 860 863 938 2 testy 839 860 863 938 839 1 test 966 968 983 993 863 938 2
A 4 B 33 ALG 2010/04 Hledání v seřazeném poli — binární, RYCHLEJŠÍ najdi 863 ! Hledání kopíruje strukturu binárního stromu 836 603 939 363 693 388 638 860 803 839 833 968 863 4 966 938 983 993 369 388 603 638 693 803 836 839 860 863 938 939 966 968 983 993 3
A 4 B 33 ALG 2010/04 Hledání v seřazeném poli — binární, RYCHLEJŠÍ N k … N =2 k . . . 8 3 4 2 8 =23 4 =22 Doba hledání 2 1 0 … 1 1 2 =2 1 =20 N = 2 k => k = log 2(N) 4
A 4 B 33 ALG 2010/04 Interpolační hledání Pole a[ ] Najdi q = 939 363 369 388 603 638 693 803 836 839 860 863 938 939 966 968 983 993 0 1 first 2 13 15 position 17 last Jsou-li hodnoty v poli rozloženy víceméně pravidelně, je možno použít lineární interpolaci. Poloha prvku v poli by měla přibližně odpovídat jeho velikosti. (q – a[first]) position = first + -------- *(last – first) a[last]-a[first] Celá část! 939 - 363 position = 0 + ------ *(17 – 0) = 15. 54 993 - 363 5
A 4 B 33 ALG 2010/04 Interpolační hledání Pole a[ ] Najdi q = 939 363 369 388 603 638 693 803 836 839 860 863 938 939 966 968 983 993 0 1 first 2 13 position 14 15 last 17 Když se na vypočtené pozici prvek nenalézá, je buď vlevo nebo vpravo od ní a pak lze (rekurzivně) vzít za výchozí interval příslušnou levou nebo pravou část pole a výpočet opakovat. (q – a[first]) position = first + -------- *(last – first) a[last]-a[first] Celá část! 939 - 363 position = 0 + ------ *(15 – 0) = 14. 12 968 - 363 6
A 4 B 33 ALG 2010/04 Interpolační hledání Pole a[ ] Najdi q = 939 363 369 388 603 638 693 803 836 839 860 863 938 939 966 968 983 993 0 1 first 2 13 position 14 15 last 17 Když se na vypočtené pozici prvek nenalézá, je buď vlevo nebo vpravo od ní a pak lze (rekurzivně) vzít za výchozí interval příslušnou levou nebo pravou část pole a výpočet opakovat. (q – a[first]) position = first + -------- *(last – first) a[last]-a[first] Celá část! 939 - 363 position = 0 + ------ *(14 – 0) = 13. 37 966 - 363 Hotovo 7
A 4 B 33 ALG 2010/04 Interpolační hledání interpol(int [] arr, int q) { int first = 0; int last = length(arr); do { pos = first + round((q–arr[first])/(arr[last]–arr[first]) *(last-first) ); if (arr[pos] < q) first = pos+1; // check left side else if (arr[pos] > q) last = pos-1; //check right side } while ((arr[pos] != q) && (first < last)); return pos; } 8
A 4 B 33 ALG 2010/04 Hledání v seřazeném poli — srovnání rychlostí Velikost Lineární hledání Interpolační hledání Binární hledání pole N průměrný případ cca průměrný /nejhorší případ 10 5. 5 1. 60 7 9 30 15. 5 2. 12 9 11 100 50. 5 2. 56 13 15 300 150. 5 2. 89 17 19 1 000 500. 5 3. 18 19 21 3 000 1 500. 5 3. 41 23 25 10 000 5 000. 5 3. 63 27 29 30 000 15 000. 5 3. 80 29 31 100 000 50 000. 5 3. 96 33 35 300 000 150 000. 5 4. 11 37 39 1 000 500 000. 5 4. 24 39 41 Zřejmě (n) Na náhodném rovnoměrném rozdělení, teoreticky (log(N))) Podle struktury binárního stromu (log(n)) 9
A 4 B 33 ALG 2010/04 Binární vyhledávací strom V levém podstromu každého uzlu jsou všechny klíče menší. Y V pravém podstromu každého uzlu jsou všechny klíče větší. >Y <Y 51 34 13 40 22 8 18 8 76 68 92 73 45 25 70 74 13 18 22 25 34 40 45 51 68 70 73 74 76 92 10
A 4 B 33 ALG 2010/04 Binární vyhledávací strom BVS nemusí být a nebývá vyvážený. 51 34 BVS nemusí být a nebývá pravidelný. Výpisem prvků BVS v pořadí INORDER získáme uspořádané hodnoty klíčů. 13 8 40 22 18 76 68 45 25 92 73 70 74 BVS je flexibilní díky operacím: Find – najdi prvek s daným klíčem Insert – vlož prvek s daným klíčem Delete – (najdi a) odstraň prvek s daným klíčem 11
A 4 B 33 ALG 2010/04 Implementace binárního stromu -- C Strom Uzel Reprezentace uzlu key left right typedef struct Node { 73501 9968 497 int key; struct Node *left; struct Node *right; } NODE; 12
A 4 B 33 ALG 2010/04 Implementace binárního stromu -- java public class Node { public Node left; public Node right; public int key; public Node(int k) { key = k; left = null; right = null; } } Strom Uzel 6084 335 22107 public class Tree { public Node root; public Tree() { root = null; } } 13
A 4 B 33 ALG 2010/04 Operace Find v BVS 51 Najdi 18 34 Každá operace se stromem začíná v kořeni. 13 8 40 22 18 76 68 45 25 92 73 70 74 Iterativně Node find(int k, Node node){ while (true) { if (node == null) return null; if (node->key == k) return node; if (k < node->key) node = node->left; else node = node->right; } } 14
A 4 B 33 ALG 2010/04 Operace Find v BVS 51 Najdi 18 34 Každá operace se stromem začíná v kořeni. 13 8 40 22 18 76 68 45 25 92 73 70 74 Rekurzivně Node if if if find. Rec(int k, Node node){ (node == null) return null; (node. key == k) return node; (k < node->key) return find. Rec(k, node->left); else return find. Rec(k, node->right) ; } } 15
A 4 B 33 ALG 2010/04 Operace Insert v BVS 51 Vlož 42 34 13 8 76 40 22 18 68 45 25 42 92 73 70 74 Sem patří 42 Insert 1. Najdi místo (jako ve Find) pro list, kam patří uzel s daným klíčem. 2. Vytvoř tento uzel a vlož jej do stromu. 16
A 4 B 33 ALG 2010/04 Operace Insert v BVS iterativně Node insert (int k, Node node) { if (node == null){ Node new. Node =. . . ; return new. Node; } while (true) if (node->key == k) return null; if (node->key > k) if (node->left == null) { Node new. Node =. . . ; node->left = new. Node; return new. Node; } else node = node->left; else if(node->right == null){ Node new. Node =. . . ; node->right = new. Node; return new. Node; } else node = node->right; } } } // empty tree // create node with key k //can't insert a duplicate // create node with key k // similarly to the right 17
A 4 B 33 ALG 2010/04 Operace Insert v BVS rekurzivně Node insert. Rec (int k, Node node, Node parent. Node) { if (node == null){ // empty tree Node new. Node =. . . ; // create node with key k if(parent. Node != null){ if(parent. Node->key > k) parent. Node->left = new. Node; else parent. Node->right = new. Node; return new. Node; } if (node->key == k) return null; //can't insert a duplicate if (node->key > k) // chose direction return insert. Rec(k, node->left, node); else return insert. Rec(k, node->right, node); } 18
A 4 B 33 ALG 2010/04 Stavba BVS operací Insert insert 40 40 40 insert 70 20 40 insert 60 60 50 60 40 insert 30 40 insert 50 20 60 60 30 50 insert 20 20 60 50 50 70 40 insert 10 40 70 20 10 60 30 50 70 19
A 4 B 33 ALG 2010/04 Tvar budovaného BVS závisí na pořadí vkládání dat. insert 50 insert 70 50 50 30 20 50 insert 30 30 30 insert 20 50 30 20 60 70 10 50 insert 40 50 30 70 insert 10 50 insert 60 60 30 60 20 60 40 70 10 20
A 4 B 33 ALG 2010/04 Operace Delete v BVS (I. ) Smazání uzlu s 0 potomky (= listu) 51 Smaž 25 34 13 8 76 40 22 18 68 45 25 42 92 73 70 74 Odsud 25 zmizí. Delete I. Najdi daný uzel (jako ve Find) a odstraň ukazatel na něj z jeho rodiče. 21
A 4 B 33 ALG 2010/04 Operace Delete v BVS (II. ) Smazání uzlu s 1 potomkem 51 Smaž 68 34 13 8 76 40 22 18 68 45 42 92 73 70 74 Odsud 25 zmizí. Z ukazatele 76 --> 68 se stane ukazatel 76 --> 73. Delete II. Najdi daný uzel (jako ve Find) a ukazatelem z jeho rodiče na něj ukaž na jeho (jediného!) potomka. 22
A 4 B 33 ALG 2010/04 Operace Delete v BVS (II. ) Smazání uzlu s 1 potomkem Před 51 34 Smaž 68 13 8 76 40 22 68 92 45 73 42 18 70 74 Po 51 34 13 8 76 22 18 73 40 45 70 92 74 42 23
A 4 B 33 ALG 2010/04 Operace Delete v BVS (IIIa. ) Smazání uzlu s 2 potomky 51 Smaž 34 x 34 76 13 8 22 18 Odsud 34 zmizí. 68 40 38 36 45 92 73 70 74 y Na jeho místo nastoupí 36. Delete IIIa. 1. Najdi daný uzel x (jako ve Find) a dále najdi nejlevější (=nejmenší klíč) uzel y v pravém podstromu x. 2. Z uzlu y ukaž na potomky uzlu x, z rodiče y ukaž na potomka y místo y, z rodiče x ukaž na y. 24
A 4 B 33 ALG 2010/04 Operace Delete v BVS (IIIa. ) Před 51 x Smaž 34 34 76 13 zanikající hrany/ukazatele/reference 8 40 38 22 18 y vznikající hrany/ukazatele/reference 68 45 92 73 74 70 36 Po 51 y 13 8 76 40 22 18 36 38 68 45 92 73 70 74 25
A 4 B 33 ALG 2010/04 Operace Delete v BVS (IIIb. ) je ekvivalentní Delete IIIa. Smazání uzlu s 2 potomky 51 Smaž 34 x 13 8 y 18 34 76 40 22 68 45 42 92 73 70 74 Odsud 34 zmizí. Na jeho místo nastoupí 22. Delete IIIb. 1. Najdi daný uzel x (jako ve Find) a dále najdi nepravější (=největší klíč) uzel y v levém podstromu x. 2. Z uzlu y ukaž na potomky uzlu x, z rodiče y ukaž na potomka y místo y, z rodiče x ukaž na y. 26
A 4 B 33 ALG 2010/04 Operace Delete v BVS (IIIb. ) je ekvivalentní Delete IIIa. Smaž 34 Před 51 x zanikající hrany/ukazatele/reference 34 13 40 y 8 vznikající hrany/ukazatele/reference 76 22 68 92 45 73 42 18 74 70 Po 51 Je nutno ošetřit případ, kdy přesouvaný uzel y má sám následníka, tedy je na něj nutno aplikovat variantu Delete II. y 13 8 22 76 40 18 68 45 42 92 73 70 74 27
A 4 B 33 ALG 2010/04 Operace Delete v BVS Node delete (int k, Node node) {. . . // homework. . . } Asymptotické složitosti operací Find, Insert, Delete v BVS s n uzly Operace Vyvážený Možná nevyvážený Find (log(n)) (n) Insert (log(n)) (n) Delete (log(n)) (n) 28
A 4 B 33 ALG 2010/04 ALG 05 Fin
- Slides: 30