Stáhnout prezentaci
Prezentace se nahrává, počkejte prosím
ZveřejnilJiří Havel
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
Podobné prezentace
© 2024 SlidePlayer.cz Inc.
All rights reserved.