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 Searching (Vyhledávání)
Typical operations Typical operations Implementation in an array Sequential search Binary search Binary search tree – BST (BVS) Node representation DSA

3 Searching (Vyhledávání)
Input: a set of n keys, a query key q Problem description: Where is q? H D N B F J S A C E G I M P V G? DSA

4 Searching (Vyhledávání)
Input: a set of n keys, a query key q Problem description: Where is q? H D N B F J S A C E G I M P V G DSA

5 Searching (Vyhledávání)
Input: a set of n keys, a query key q Problem description: Where is q? H D N B F J S A C E G I M P V L? DSA

6 Searching (Vyhledávání)
Input: a set of n keys, a query key q Problem description: Where is q? H D N B F J S A C E G I M P V L not found DSA

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

8 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 DSA

9 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) DSA

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

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

12 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 DSA

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

14 Searching in unsorted array
Unsorted array P(n) = O(n) Sequential search Q(n) = O(n) insert I(n) = O(1) delete D(n) = O(n) min, max in O(n) 1 2 3 4 5 B D A C size 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; } Java-like pseudo code DSA

15 Searching in unsorted array
Unsorted array with sentinel Sequential search still Q(n) = O(n) 1 2 3 4 5 B D E A C size search(“E“, a) 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; } Java-like pseudo code DSA

16 Searching in sorted array
Binary search Q(n) = O(log(n)) insert I (n) = O(n) delete D(n) = O(n) min, max in O(1) 1 2 3 4 5 A B C E size 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 } Java-like pseudo code DSA

17 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 Java-like pseudo code DSA

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

19 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 uL z levého podstromu platí: klíč(uL)  klíč(u) pro všechny uzly uR z pravého podstromu platí: klíč(uR)  klíč(u) u je kořen DSA

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

21 Binární vyhledávací strom Binary Search Tree
= 7 2 9 1 5 8 10 3 6 < > DSA

22 Tree node representation
key left right search min, max key left right key left right DSA

23 Tree node representation
parent key search min, max predecessor, successor left right parent parent key key left right left right DSA

24 Tree node representation
See in Lesson6, page 17-18 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 = …; } 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; }} DSA

25 Searching BST G < H G > D G > F
J S G > F A C E G I M P V G = G => stop, element found DSA

26 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 DSA

27 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 DSA

28 Minimum in BST H D N B F J S A C E G I M P V DSA

29 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 DSA

30 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 DSA

31 Maximum in BST H D N B F J S A C E G I M P DSA

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

33 Successor in BST 1/4 in the sorted order (in-order tree walk)
1. Right son exists H D N B F J S A C E G I M P succ(B) -> C succ(H) -> I How? DSA

34 Successor in BST 2/4 in the sorted order (in-order tree walk)
1. Right son exists H D N B F J S A C E G I M P succ(B) -> C succ(H) -> I Find the minimum in the right tree = min( x.right ) DSA

35 Successor in BST 3/4 in the sorted order (in-order tree walk)
2. Right son is null H D N B F J S A C E G I M P succ(C) -> D succ(G) -> H How? DSA

36 Successor in BST 4/4 in the sorted order (in-order tree walk)
2. Right son is null x = node on path y = its parent H D N B F J S A C E G I M P y x succ(C) -> D succ(G) -> H Find the minimal parent to the right (the minimal parent the node is left from) DSA

37 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 DSA

38 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 DSA

39 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? DSA

40 Operational Complexity
H D N B F J S A C E G I M P V H D B F J A C E G I M h = log2(n) h = n!!! O(log(n)) O(n)!!! => balance the tree!!! DSA

41 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. DSA

42 Insert (vložení prvku)
x = node on path y = its parent H L > H D N L < N B F J y S x A C E G I M P V insert L 1. find the parent leaf 2. connect new element as a new leaf DSA

43 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 DSA

44 Delete (odstranění prvku) a) delete a leaf (smaž list)
H D N B F J S A C E G I M P V H D N B F J S A C E I M P V delete(G) e=y leaf has no children -> it is simply removed DSA

45 Delete (odstranění prvku) b) with one child (vnitřní s potomkem)
delete(F) D N e=y B F J S B E J S A C E x I M P V A C I M P V node has one child -> splice the node out (přemosti) DSA

46 Delete (odstranění prvku) c) with two children (se 2 potomky)
B F J S A C E I M P V y e x F delete(H) D N B E J S A C I M P V node has two children -> replace it with successor with only one child DSA

47 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 B F A C E y e x H D B F A C E G y = e H D B F A C E y = e a) b) C) DSA

48 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) e H D B F A C E G y = e H D B F A C E y = e H D y B F x x A C E a) b) C) DSA

49 Delete (odstranění prvku)
... // link x with parent of y – link up if( x != null ) x.parent = y.parent; e H D B F A C E G y = e H D B F A C E y = e H D y B F x x A C E a) b) C) DSA

50 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; ... F E y x e H H H D D D Link to null y = e y B F B F B F y = e x x A C E G A C E A C E a) b) C) DSA

51 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 e e H F D D y y B F B E x A C E A C DSA

52 And the operational complexity?

53 Operational Complexity
H D N B F J S A C E G I M P V H D B F J A C E G I M h = log2(n) h = n!!! O(log(n)) O(n)!!! => balance the tree!!! DSA

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

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

56 výška + počet potomků - 1-2 strom, ...
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 DSA

57 Tree balancing Strong criterion (Ideal case) Weaker criterion
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 DSA

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

59 Levá rotace (Left rotation)
root A B II B p1 A x I z y z h-1 x y h 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; } Java-like pseudo code DSA

60 Pravá rotace (right rotation)
root B A II p1 A B z x I x y h-1 y z h h+1 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; } Java-like pseudo code DSA

61 LR rotace (left-right rotation)
root C IV B II p1 A A C 2 1 z III I B p2 x y h-1 z w w x y h h+1 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; } Java-like pseudo code DSA

62 RL rotace (right- left rotation)
root A II B IV C p1 A C w 2 1 I III p2 B x y h-1 w z z x y h h+1 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; } Java-like pseudo code DSA

63 Tree balancing Balancing criteria Rotations AVL tree Weighted tree
DSA

64 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} DSA

65 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 DSA

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

67 AVL strom před vložením uzlu AVL tree before node insertion
-1 2 3 1 1 2 2 1 -1 -1 -1 1 1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 DSA

68 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 1 -1 -1 -1 -1 -1 -1 DSA

69 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 1 2 1 2 1 -1 -1 1 -1 -1 insert left 1 -1 -1 -1 -1 -1 -1 -1 DSA

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

71 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 1 2 1 2 -1 -1 -1 1 -1 -1 insert right -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 DSA

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

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

74 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 Node with balance 0 n+1 n n n Sub-tree of height n n n n n Sub-tree below of height n n DSA

75 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 B B 1 2 n+1 n n+2 n A A 1 n n n n n+1 n insert left n n n n DSA

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

77 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 C C 1 2 n+1 n n+2 n A A -1 n n n n n n+1 B B 1 n-1 n-1 n n-1 insert right n n-1 n-1 n n-1 n-1 DSA

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

79 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 C C 1 2 n+1 n n+2 n A A -1 n n n n n n+1 B B 1 n-1 n-1 n n-1 insert right n n-1 n-1 n n-1 n-1 DSA

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

81 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 DSA

82 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 // balance tree, if necessary } Java-like pseudo code DSA

83 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 DSA

84 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; } ... DSA

85 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 if( e.key < fcur.key ) fcur.left = help; else fcur.right = help; } DSA

86 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 DSA

87 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 log2(n+1)  h(S)  log2(n+2)-0.328 [Hudec96], [Honzík85] DSA

88 Tree balancing Balancing criteria Rotations AVL tree Weighted tree
DSA

89 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) = ( |UL| + 1) / ( |U| + 1 ), když u je kořen podstromu SU S UL = množina uzlů levého podstromu SU U = množina uzlů podstromu SU DSA

90 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 + log2(n+1) - 1) / log2 (1 / (1- )) [Hudec96], [Mehlhorn84] DSA

91 Weight balanced tree example
(5+1) / (12+1) = 6/13 (3+1) / (5+1) = 2/3 H (3+1) / (6+1) = 4/7 (1+1) / (3+1) = 1/2 D N (1+1) / (2+1) = 2/3 1/2 B F J S 1/2 A C I M P 1/2 1/2 1/2 1/2 (0+1) / (1+1) = 1/2 DSA

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

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


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