Prezentace se nahrává, počkejte prosím

Prezentace se nahrává, počkejte prosím

Datové struktury a algoritmy Část 7 Vyhledávání a vyhledávací stromy Searching and Search Trees Petr Felkel.

Podobné prezentace


Prezentace na téma: "Datové struktury a algoritmy Část 7 Vyhledávání a vyhledávací stromy Searching and Search Trees Petr Felkel."— Transkript prezentace:

1 Datové struktury a algoritmy Část 7 Vyhledávání a vyhledávací stromy Searching and Search Trees Petr Felkel

2 2 / 93 DSA Searching (Vyhledávání) Typical operations Implementation in an array Sequential search Binary search Binary search tree – BST (BVS) Node representation Typical operations

3 3 / 93 DSA Searching (Vyhledávání) H D N BFJS ACEGIMPV G? Input: a set of n keys, a query key q Problem description: Where is q?

4 4 / 93 DSA Searching (Vyhledávání) H D N BFJS ACEGIMPV G Input: a set of n keys, a query key q Problem description: Where is q?

5 5 / 93 DSA Searching (Vyhledávání) H D N BFJS ACEGIMPV Input: a set of n keys, a query key q Problem description: Where is q? L?

6 6 / 93 DSA Searching (Vyhledávání) Input: a set of n keys, a query key q Problem description: Where is q? H D N BFJS ACEGIMPV L not found

7 7 / 93 DSA Search space Key empty pred, succ insert,delete,replace search Elem getKey min,max

8 8 / 93 DSA Searching (Vyhledávání) Search space (lexicon) Static - fixed -> simpler implementation -> change means new release Dynamic - changes in time -> more complex implementation -> change by insert,delete,replace

9 9 / 93 DSA Searching (Vyhledávání) Operations: k…key, e…element with key k x…data set {subtree root node, array, table,…} Informal list: search(x,k) min(x), max(x) pred(x,e), succ(x,e) insert(x,e), delete(x,e), replace(x,e)

10 10 / 93 DSA Searching (Vyhledávání) Typical operations Implementation In array Sequential search Binary search Binary search tree – BST (BVS) Node representation

11 11 / 93 DSA Implementation Address search (přímý přístup) Compute position from key pos = f(k) Array, table,… Associative search Element located in relation to others

12 12 / 93 DSA Implementation quality P(n) = memory complexity Q(n) = time complexity of search, query I(n) time complexity of insert D(n) time complexity of delete

13 13 / 93 DSA Searching (Vyhledávání) Typical operations Implementation In an array Sequential search Binary search Binary search tree – BST (BVS) Node representation

14 14 / 93 DSA Searching in unsorted array Unsorted arrayP (n) = O(n) Sequential search Q(n) = O(n) insert I(n) = O(1) delete D(n) = O(n) min, max in O(n) nodeT seqSearch( key k, nodeT a[] ) { int i; while( (i < a.size) && (a[i].key != k) ) i++; if( i < a.size ) return a[i]; else return NODE_NOT_FOUND; } BDAC size Java-like pseudo code

15 15 / 93 DSA Searching in unsorted array nodeT seqSearchWithSentinel( key k, nodeT a[] ) { int i; a[a.size] = createArrayElement( k ); // place a sentinel while( a[i].key != k ) // and save one test i++; // per step if( i < a.size ) return a[i]; else return NODE_NOT_FOUND; } BDEAC size Unsorted array with sentinel Sequential search still Q(n) = O(n) Java-like pseudo code search(“ E “, a)

16 16 / 93 DSA Searching in sorted array nodeT binarySearch( key k, nodeT sortedArray[] ) { pos = bs( k, sortedArray, 0, sortedArray.size - 1 ); if( pos >= 0 ) return sortedArray[pos]; else return NODE_NOT_FOUND; // -(pos+1) contains the position // to insert the node with key k } BACE size Sorted array Binary search Q(n) = O(log(n)) insert I (n) = O(n) delete D(n) = O(n) min, max in O(1) Java-like pseudo code

17 17 / 93 DSA Binary search //Recursive version int bs( key k, nodeT a[], int first, int last ) { if( first > last ) return –(first + 1); // not found int mid = ( first + last ) / 2; if( k < a[mid].key ) return bs( k, a, first, mid – 1); if( k > a[mid].key ) return bs( k, a, mid + 1, last ); return mid; // found! } // Iterative version int bs(key k, nodeT a[], int first, int last ) { while (first <= last) { int mid = (first + last) / 2; // compute the mid point if (key > sortedArray[mid]) first = mid + 1; else if (key < sortedArray[mid]) last = mid - 1; else return mid; // found it. } return -(first + 1); // failed to find key } Java-like pseudo code

18 18 / 93 DSA Searching (Vyhledávání) Typical operations Implementation In an array Sequential search Binary search Binary search tree – BST (BVS) Node representation

19 19 / 93 DSA Binární vyhledávací strom (BVS) Kořenový binární strom uzel má 0, (1), 2 následníky Binární vyhledávací strom (BVS) uspořádaný kořenový binární strom pro všechny uzly u L z levého podstromu platí: klíč(u L )  klíč(u) pro všechny uzly u R z pravého podstromu platí: klíč(u R )  klíč(u) u je kořen

20 20 / 93 DSA Binary Search Tree (BST) Rooted binary tree node has 0, (1), 2 successors Binary Search Tree (BST) Ordered rooted binary tree for each node u L in the left sub-tree: key(u L )  key(u) for each node u R in the right sub-tree: key(u)  key(u R ) u is the root

21 21 / 93 DSA Binární vyhledávací strom Binary Search Tree < > < > < > < > =

22 22 / 93 DSA Tree node representation key leftright key leftright key leftright search min, max

23 23 / 93 DSA Tree node representation key leftright parent key leftright parent key leftright parent search min, max predecessor, successor

24 24 / 93 DSA Tree node representation public class Node { public Node left; public Node right; public int key; public Node(int k) { key = k; left = null; right = null; dat = …; } public class Tree { public Node root; public Tree() { root = null; }} public class Node { public Node parent; public Node left; public Node right; public int key; public Node(int k) { key = k; parent = null; left = null; right = null; dat = …; } See in Lesson6, page 17-18

25 25 / 93 DSA Searching BST H D N BFJS ACEGIMPV G < H G > D G > F G = G => stop, element found

26 26 / 93 DSA Searching BST - recursively Node TreeSearch( Node x, key k ) { if(( x == null ) or ( k == x.key )) return x; if( k < x.key ) return TreeSearch( x.left, k ); else return TreeSearch( x.right, k ); } Java-like pseudo code

27 27 / 93 DSA Searching BST - iteratively Node TreeSearch( Node x, key k ) { while(( x != null ) and (k != x.key )) { if( k < x.key )x = x.left; else x = x.right; } return x; } Java-like pseudo code

28 28 / 93 DSA Minimum in BST H D N BFJS ACEGIMPV

29 29 / 93 DSA Minimum in BST - iteratively Node TreeMinimum( Node x ) { if( x == null ) return null; while( x.left != null ) { x = x.left; } return x; } Java-like pseudo code

30 30 / 93 DSA Maximum in BST - iteratively Node TreeMaximum( Node x ) { if( x == null ) return null; while( x.right != null ) { x = x.right; } return x; } Java-like pseudo code

31 31 / 93 DSA Maximum in BST H D N BFJS ACEGIMP

32 32 / 93 DSA Successor in BST 1/4 in the sorted order (in-order tree walk) Two cases: 1. Right son exists 2. Right son is null

33 33 / 93 DSA Successor in BST 1/4 in the sorted order (in-order tree walk) H D N BFJS ACEGIMP succ(B) -> C succ(H) -> I How? 1. Right son exists

34 34 / 93 DSA Successor in BST 2/4 in the sorted order (in-order tree walk) H D N BFJS ACEGIMP succ(B) -> C succ(H) -> I Find the minimum in the right tree = min( x.right ) 1. Right son exists

35 35 / 93 DSA Successor in BST 3/4 in the sorted order (in-order tree walk) H D N BFJS ACEGIMP succ(C) -> D succ(G) -> H How? 2. Right son is null

36 36 / 93 DSA Successor in BST 4/4 in the sorted order (in-order tree walk) H D N BFJS ACEGIMP succ(C) -> D succ(G) -> H Find the minimal parent to the right (the minimal parent the node is left from) 2. Right son is null x = node on path y = its parent x y

37 37 / 93 DSA Successor in BST - recursively in the sorted order (in-order tree walk) Node TreeSuccessor( Node x ) { if( x == null ) return null; if( x.right != null ) return TreeMinimum( x.right ); y = x.parent; while( (y != null) and (x == y.right)) { x = y; y = x.parent; } return y; } Java-like pseudo code

38 38 / 93 DSA Predecessor in BST - recursively in the sorted order (in-order tree walk) Node TreePredecessor( Node x ) { if( x == null ) return null; if( x.left != null ) return TreeMaximum( x.right ); y = x.parent; while( (y != null) and (x == y.left)) { x = y; y = x.parent; } return y; } Java-like pseudo code

39 39 / 93 DSA Operational Complexity The following dynamic-set operations: Search, Maximum, Minimum, Successor, Predecessor can run in O(h) time on a binary tree of height h. …. what h?

40 40 / 93 DSA Operational Complexity H D N BFJS ACEGIMPV H D B F J A C E G I M h = log 2 (n) h = n!!! O(log(n)) O(n)!!! => balance the tree!!!

41 41 / 93 DSA Operational Complexity The following dynamic-set operations: Search, Maximum, Minimum, Successor, Predecessor can run in  (nlog(n)) and O(n) time on a not-balanced binary tree with n nodes.

42 42 / 93 DSA Insert (vložení prvku) H D N BFJS ACEGIMPV insert L 1. find the parent leaf 2. connect new element as a new leaf y x x = node on path y = its parent L < N L > H

43 43 / 93 DSA Insert (vložení prvku) void treeInsert( Tree t, Elem e ) { x = t.root; y = null; // t is tree root if( x == null ) t.root = e; else { while(x != null) { // find the parent leaf y = x; if( e.key < x.key ) x = x.left; else x = x.right; } // add new to parent if( e.key < y.key ) y.left = e; else y.right = e; } Java-like pseudo code

44 44 / 93 DSA Delete (odstranění prvku) a) delete a leaf (smaž list) H D N BFJS ACEGIMPV H D N BFJS ACEIMPV leaf has no children -> it is simply removed delete(G) e=y

45 45 / 93 DSA Delete (odstranění prvku) b) with one child (vnitřní s potomkem) H D N BFJS ACEIMPV node has one child -> splice the node out (přemosti) delete(F) H D N BEJS ACIMPV x e=y

46 46 / 93 DSA Delete (odstranění prvku) c) with two children (se 2 potomky) node has two children -> replace it with successor with only one child delete(H) F D N BEJS ACIMPV H D N BFJS ACEIMPV y e x

47 47 / 93 DSA Delete (odstranění prvku) Tree treeDelete( Tree t, Node e ) { Node y; // e..node to delete // find node y to splice out if(e.left == null OR e.right == null) y = e; // case a,b) 0 to 1 child else // case c) 2 children y = TreePredecessor(e); H D BF ACE y e x H D BF ACE y = e H D BF ACEG a) b) C)

48 48 / 93 DSA Delete (odstranění prvku)... // find y’s only child x if( y.left != null ) x = y.left; // non-null child of y or null else x = y.right;... //(y will be physically removed) H D BF ACE y e x H D BF ACE y = e H D BF ACEG a) b) C) x

49 49 / 93 DSA Delete (odstranění prvku)... // link x with parent of y – link up if( x != null ) x.parent = y.parent;... H D BF ACE y e x H D BF ACE y = e H D BF ACEG a) b) C) x

50 50 / 93 DSA Delete (odstranění prvku)... // link x with parent of y - link down if( y.parent == null ) t.root = x // it was root else if( y == (y.parent).left ) (y.parent).left = x; else (y.parent).right = x;... H D BF ACE y e x H D BF ACE y = e H D BF ACEG a) b) C) x F E y x E x Link to null

51 51 / 93 DSA Delete (odstranění prvku)... if( y != e ) // replace e with in-order successor { e.key = y.key; // copy the key e.dat = y.dat; // copy other fields too } return y; // To be disposed // or reused // outside } F D B AC E y e H D BF ACE y e x

52 And the operational complexity?

53 53 / 93 DSA Operational Complexity H D N BFJS ACEGIMPV H D B F J A C E G I M h = log 2 (n) h = n!!! O(log(n)) O(n)!!! => balance the tree!!!

54 54 / 93 DSA Tree balancing Balancing criteria Rotations AVL – tree Weighted tree Balancing criteria

55 55 / 93 DSA Tree balancing Why? To get the O(log n) complexity of search,... How? By local modifications reach the global goal

56 56 / 93 DSA Vyvažování stromu Silná podmínka (Ideální případ) Pro všechny uzly platí: počet uzlů vlevo = počet uzlů vpravo Slabší podmínka výška podstromů - AVL strom výška + počet potomků strom,... váha podstromů (počty uzlů) - váhově vyvážený strom

57 57 / 93 DSA Tree balancing Strong criterion (Ideal case) For all nodes: No of nodes left = No of nodes right Weaker criterion subtree heights - AVL tree height + number of children tree,... subtree weights (No of nodes) - weighted tree

58 58 / 93 DSA Tree balancing Balancing criteria Rotations AVL – tree Weighted tree

59 59 / 93 DSA Levá rotace (Left rotation) h h+1 h-1 Node leftRotation( Node root ) { // subtree root node !!! if( root == null ) return root; Node p1 = root.right;(init) if (p1 == null) return root; root.right = p1.left;(I) p1.left= root;(II) return p1; } x A B y z p1 root B A x z y I II Java-like pseudo code

60 60 / 93 DSA z Pravá rotace (right rotation) B A y x h h+1 h-1 A B z x y Node rightRotation( Node root ) {// subtree root node !!! if( root == null ) return root; Node p1 = root.left;(init) if (p1 == null) return root; root.left = p1.right;(I) p1.right= root;(II) return p1; } p1 root I II Java-like pseudo code

61 61 / 93 DSA LR rotace (left-right rotation) Node leftRightRotation( Node root ) { if(root==null)....; Node p1 = root.left; Node p2 = p1.right; (init) root.left = p2.right;(I) p2.right = root;(II) p1.right = p2.left;(III) p2.left = p1;(IV) return p2; } I II z A w y B C x III IV h h+1 h-1 z A w y p2 root C B p1 x 2 1 Java-like pseudo code

62 62 / 93 DSA Node rightLeftRotation( Node root ) { if(root==null)....; Node p1 = root.right; Node p2 = p1.left; (init) root.right = p2.left;(I) p2.left = root;(II) p1.left = p2.right;(III) p2.right = p1;(IV) return p2; } RL rotace (right- left rotation) I II w C z x B A y III IV h h+1 h-1 w C z x p2 root A B p1 y 2 1 Java-like pseudo code

63 63 / 93 DSA Tree balancing Balancing criteria Rotations AVL tree Weighted tree AVL tree

64 64 / 93 DSA Kdy použijeme kterou rotaci? AVL strom [Richta90] Výškově vyvážený strom Georgij Maximovič Adelson-Velskij a Evgenij Michajlovič Landis Výška: Prázdný strom: výška = -1 neprázdný: výška = výška delšího potomka Vyvážený strom: rozdíl výšek potomků bal = {-1, 0, 1}

65 65 / 93 DSA AVL strom (AVL tree) int height( Node t ) { if( t == null ) return -1; else return 1 + max(height( t.left ), height( t.right ) ); } int bal( Node t ) { return height( t.left ) - height( t.right ); } Java-like pseudo code

66 66 / 93 DSA 00 AVL strom - výšky a rozvážení AVL tree - heights and balance výška / height rozvážení/ balance

67 67 / 93 DSA 00 AVL strom před vložením uzlu AVL tree before node insertion

68 68 / 93 DSA AVL strom - nejmenší podstrom AVL tree - the smallest subtree Nejmenší podstrom, který se přidáním uzlu rozváží The smallest sub-tree looses its balance by insertion

69 69 / 93 DSA AVL strom - vložení uzlu doleva AVL tree - node insertion left a) Podstrom se přidáním uzlu doleva rozváží The sub-tree loses its balance by node insertion - left insert left

70 70 / 93 DSA 0 AVL strom - pravá rotace AVL tree - right rotation R rot a) Vložen doleva => korekce pravou rotací Node inserted to the left => balance by right rotation A B A B

71 71 / 93 DSA AVL strom - vložení uzlu doprava AVL tree after insertion-right b) Podstrom se přidáním uzlu doprava rozváží The sub-tree loses its balance by node insertion - right 0 insert right

72 72 / 93 DSA 0 AVL strom - pravá rotace AVL tree - right rotation LR rot b) Vložen doprava => korekce LR rotací Node inserted right => balance by the LR rotation 2 1 A B A C B C

73 73 / 93 DSA Node insertion - for general AVL sub-trees AVL tree

74 74 / 93 DSA AVL strom - nejmenší podstrom AVL tree - the smallest subtree Nejmenší podstrom, který se přidáním uzlu rozváží The smallest sub-tree looses its balance by insertion 1 0 n n n+1 n n 0 n Node with balance 0 Sub-tree of height n n n n Sub-tree below of height n

75 75 / 93 DSA AVL strom - vložení uzlu doleva AVL tree - node insertion left a) Podstrom se přidáním uzlu doleva rozváží The sub-tree loses its balance by node insertion - left 0 insert left 1 n n+1 n+2 n n n n 1 0 n n n+1 n n n n 2 A B A B

76 76 / 93 DSA AVL strom - pravá rotace AVL tree - right rotation n R rot a) Vložen doleva => korekce pravou rotací Node inserted to the left => balance by right rotation 0 1 n n+1 n+2 n n n n 2 0 n+1 n n n n 0 0 A B A B

77 77 / 93 DSA AVL strom - vložení uzlu doprava AVL tree after insertion-right b1) Podstrom se přidáním uzlu doprava rozváží The sub-tree loses its balance by node insertion - right insert right nn+2 n 0 nn+1 n-1 1 n n-1 1 nn+1 n nn n-1 0 n 0 2 n A B C A B C

78 78 / 93 DSA AVL strom - pravá rotace AVL tree - right rotation LR rot b1) Vložen doprava => korekce LR rotací Node inserted right => balance by the LR rotation 2 1 nn+2 n 0 nn+1 n-1 1 n n-1 2 n n+1 n 0 nn n-1 n n 0 0 A B C A B C

79 79 / 93 DSA AVL strom - vložení uzlu doprava AVL tree after insertion-right b2) Podstrom se přidáním uzlu doprava rozváží The sub-tree loses its balance by node insertion - right insert right nn+2 n 0 nn+1 n-1 1 n n-1 1 nn+1 n nn n-1 0 n 0 2 n A B C A B C

80 80 / 93 DSA AVL strom - pravá rotace AVL tree - right rotation LR rot b2) Vložen doprava => korekce LR rotací Node inserted right => balance by the LR rotation 2 1 nn+2 n 0 nn+1 n-1 1 n n-1 2 n n+1 n 0 nn-1 n nn 0 10 A B C A B C

81 81 / 93 DSA BST Insert without balancing avlTreeInsert( Tree t, Elem e ) { x = t.root; y = null; if( x == null ) t.root = e; else { while(x != null) { // find the parent leaf y = x; if( e.key < x.key ) x = x.left else x = x.right } // add new to parent if( e.key < y.key ) y.left = e else y.right = e } Java-like pseudo code

82 82 / 93 DSA AVL Insert (with balancing) avlTreeInsert( tree t, elem e ) { // init // 1. find place for insert // 2. if( already present ) //replace the node // else //insert new node // 3.balance tree, if necessary } Java-like pseudo code

83 83 / 93 DSA AVL Insert - variables & init avlTreeInsert( Tree t, Elem e ) { Node cur, fcur; // current sub-tree and its father Node a, b; // smallest unbalanced tree and its son Bool found; // node with the same key as e found Node help; // init found = false; cur = t.root; fcur = null; a = cur, b = null; // 1. find place for insert... Java-like pseudo code

84 84 / 93 DSA AVL Insert - find place for insert... // 1. find a place for insert while(( cur != null ) and !found ) { if( e.key == cur.key ) found = true; else { if( e.key < cur.key ) help = cur.left; else help = cur.right; if(( help != null) and ( bal(help) != 0 )){ //remember possible place for unbalance a = help; } fcur = cur; cur = cur.help; } }...

85 85 / 93 DSA AVL Insert - replace or insert new... // 2. if( already present ) replace the node value if( found ) setinfo( cur, e );// replace the node value else { // insert new node to fcur help = leaf( e ); // cons ( e, null, null ); if( fcur == null ) t.root = help; // new root else { if( e.key < fcur.key ) fcur.left = help; else fcur.right = help; }...

86 86 / 93 DSA AVL Insert - balance the subtree... // !found continues // 3.balance tree, if necessary if( bal(a) == 2 ){ // inserted left from 1 b = a.left; if( b.key < e.key ) //and right from its son a.left = leftRotation( b ); a = rightRotation( a ); } else if( bal(a) == -2){ //inserted right from -1 b = a.right; if( e.key < b.key ) // and left from its son a.right = rightRotation( b ); a = leftRotatation( a ); } // else tree remained balanced } // !found }

87 87 / 93 DSA AVL - výška stromu Pro strom S s n uzly platí Výška h(S) je max o 45% větší než u ideálně vyváženého stromu log 2 (n+1)  h(S)  log 2 (n+2) [Hudec96], [Honzík85]

88 88 / 93 DSA Tree balancing Balancing criteria Rotations AVL tree Weighted tree

89 89 / 93 DSA Váhově vyvážené stromy Weight balanced trees (stromy s ohraničeným vyvážením) Váha uzlu u ve stromě S: v (u) = 1/2, když je u listem v (u) = ( |U L | + 1) / ( |U| + 1 ), když u je kořen podstromu S U  S U L = množina uzlů levého podstromu S U U = množina uzlů podstromu S U

90 90 / 93 DSA Váhově vyvážené stromy Weight balanced trees Stromy s ohraničeným vyvážením  : Strom S má ohraničené vyvážení , 0    0,5, jestliže pro všechny uzly S platí   v(u)  1-  Výška h(S) stromu S s ohraničeným vyvážením  h(S)  (1 + log 2 (n+1) - 1) / log 2 (1 / (1-  )) [Hudec96], [Mehlhorn84]

91 91 / 93 DSA Weight balanced tree example H D N BFJS ACIMP (1+1) / (3+1) = 1/2 1/2 (0+1) / (1+1) = 1/2 (3+1) / (6+1) = 4/7 1/2 (3+1) / (5+1) = 2/3 (5+1) / (12+1) = 6/13 (1+1) / (2+1) = 2/3

92 92 / 93 DSA Levá rotace (Left rotation) [Hudec96] x A B y z VAVA B A x z y VBVB V A ’ = V A / ( V A + (1- V A ). V B ) V B ’ = V A + (1- V A ). V B VA’VA’ V B ’

93 93 / 93 DSA V A ’ = V A / ( V A + (1- V A ) V B V C ) V B ’ = V B (1- V C ) / (1- V B V C ) V C ’ = V A + (1- V A ). V A V B [Hudec96] RL rotace (right- left rotation) w C z x B A y w C z x A B y 2 1 VAVA VCVC VBVB VA’VA’ V B ’ V C ’


Stáhnout ppt "Datové struktury a algoritmy Část 7 Vyhledávání a vyhledávací stromy Searching and Search Trees Petr Felkel."

Podobné prezentace


Reklamy Google