trees 1 are lists enough? for correctness sure want to - - PowerPoint PPT Presentation

trees
SMART_READER_LITE
LIVE PREVIEW

trees 1 are lists enough? for correctness sure want to - - PowerPoint PPT Presentation

trees 1 are lists enough? for correctness sure want to effjciently access items better than linear time to fjnd something 2 want to represent relationships more naturally inter-item relationships in lists 1 2 3 4 5 List: nodes


slide-1
SLIDE 1

trees

1

slide-2
SLIDE 2

are lists enough?

for correctness — sure want to effjciently access items

better than linear time to fjnd something

want to represent relationships more naturally

2

slide-3
SLIDE 3

inter-item relationships in lists

1 2 3 4 5

List: nodes related to predecessor/successor

3

slide-4
SLIDE 4

trees

trees: allow representing more relationships

(but not arbitrary relationships — see graphs later in semester)

restriction: single path from root to every node

implies single path from every node to every other node (possibly through root)

4

slide-5
SLIDE 5

natural trees: phylogenetic tree

image: Ivicia Letunic and Mariana Ruiz Villarreal, via the tool iTOL (Interative Tree of Life), via Wikipedia

5

slide-6
SLIDE 6

natural trees: phylogenetic tree (zoom)

image: Ivicia Letunic and Mariana Ruiz Villarreal, via the tool iTOL (Interative Tree of Life), via Wikipedia

6

slide-7
SLIDE 7

natural trees: Indo-European languages

Kashubian INDO-IRANIAN IRANIAN INDO-ARYAN WESTERN EASTERN WESTERN INDIC Gandhari CENTRAL INDIC Maharashtri Sindhi Konkani Gorani Balochi Kurdish Parthian Talysh Gilaki Scythian Sarmatian Alanic CELTIC Manx Irish Cornish Breton GOIDELIC BRYTHONIC Galatian Celtiberian TOCHARIAN ARMENIAN ANATOLIAN ALBANIAN GERMANIC EAST Gothic Vandalic Burgundian Dutch Afrikaans Icelandic Faroese Norwegian Norn Swedish Danish Old Norse BALTO-SLAVIC BALTIC SLAVIC WEST EAST SOUTH Old West Slavic ITALIC Galindan Prussian Sudovian Latvian Lithuanian Selonian Semigallian Belorussian Russian Rusyn Bulgarian Macedonian Czech Slovak Pomeranian LATINO-FALISCAN Latin Faliscan SABELLIC Classical Latin Vulgar Latin EASTERN Romanian Dalmatian Aromanian ITALO-WESTERN ITALO-DALMATIAN IBERIAN Italian Astur-Leonese Galician-Portuguese INDO-EUROPEAN Hittite Luwian Lycian Carian Palaic Lydian PAHARI Dogri Garhwali DARDIC Kashmiri Pashayi Magahi Bhojpuri Maithili Oriya Magadhi Dhivehi Avestan Bactrian Sogdian Yaghnobi Tat Old Persian Persian Tajik Juhuru Aequian Marsian Oscan Sardinian Logudorese Campidanese Ecclesiastical Latin Gaulish Lepontic Noric Old West Norse Old East Norse Standard German Old High German Flemish Yiddish Old Frisian Old English ANGLO-FRISIAN Scots English Turfanian Kuchean INSULAR CONTINENTAL Armenian Albanian ROMANCE Sinhalese Vedda Vedic Sanskrit Hindi Urdu Dakhini Rekhta Mozarabic Aragonese Walloon Emilian Rhaetian Friulian HELLENIC Aegean Mycenaean DORIAN Northwest Greek Doric Attic Arcado Cypriot Ionic Epic Greek Classical Greek Koine Greek Greek Tsakonian Low German Cumbric Welsh Scottish Gaelic Gallo Volscian Umbrian Saka Ossetian Pashto Pamiri Bengali Bhil Marathi Shina Kumaoni WEST Prakrit INSULAR INDIC Potwari Punjabi Domari Waziri Yidgha Shughni Vanji Sarikoli Khotanese Khwarezmian Median Mazanderani Shahmirzadi CASPIAN Zazaki Zaza-Gorani Middle Persian Bukhori Dari Lurish Bakhtiari Old East Slavic Ukrainian Ruthenian Old Novgorod Old Church Slavonic Church Slavonic Serbo-Croatian LECHITIC Sorbian Polish Ivernic Pictish Common Brittonic Hazaragi Deilami Greenlandic Norse Old Gutnish Pisidian Old Saxon Old Dutch Yola Assamese WEST EAST CENTRAL GERMAN Limburgish Old East Low Franconian SOUTH NORTH Niya Shauraseni Nuristani HINDUSTANI BIHARI ACHAEAN AEOLIC Beotian Thessalian EAST Yazgulami NORTH SOUTH Nepali Palpa Halbi Chittagonian NORTH CENTRAL EASTERN Lahnda Paisaci Haryanvi Luxembourgish Ripuarian Thuringian Kumzari Alemannic Austro-Bavarian Cimbrian Istriot Sassarese Neapolitan Sicilian GALLO-IBERIAN OCCITAN GALLIC CISALPINE Spanish Portuguese Galician Catalan Occitan Ligurian Lombard Piedmontese Venetian Arpitan Romansh UPPER GERMAN Swiss German Old Polish Romani Gujarati Rajasthani Norman French Pali Sanskrit Asturian Leonese Mirandese Slovene Serbian Croatian Bosnian WESTERN EASTERN Knaanic Czech-Slovak Polabian Silesian Fala Ladino Extremaduran Old Spanish Ladin Corsican Istro-Romanian Megleno-Romanian LANGUE D'OÏL Crimean Gothic North Frisian Saterland Frisian West Frisian Elfdalian LOW FRANCONIAN Eonavian WEST

image: via Wikipedia/Mandrak

7

slide-8
SLIDE 8

list to tree

predecessor element successor list — up to 2 related nodes parent element left child left child binary tree — up to 3 related nodes (list is special-case)

8

slide-9
SLIDE 9

more general trees

parent element child 1 child 2 child n

tree — any number of relationships (binary tree is special case) at most one parent

9

slide-10
SLIDE 10

tree terms (1)

A B C E F G D H parent child root: node with no parents leafs: nodes with no children siblings: nodes with the same parent

10

slide-11
SLIDE 11

paths and path lengths

A B C E F G D H path: sequence of nodes n1, n2, . . . , nk such that ni is parent of ni+1 example: {B, D, H} length (of path): number of edges in path example: 2 (B → D and D → H) internal path length: sum of depth of nodes example: 6 = 1 + 2 + 3

11

slide-12
SLIDE 12

tree/node height

A B C E F G D H parent child height (of a node): length of longest path to leaf height (of a tree): height of tree’s root (this example: 3) 3 2 1 1

12

slide-13
SLIDE 13

tree/node depth

A B C E F G D H parent child depth (of a node): length of path to root 1 2 3 1 2 2 2

13

slide-14
SLIDE 14

fjrst child/next sibling

class TreeNode { private: string element; TreeNode *firstChild; TreeNode *nextSibling; public: ... }; home aaron cs2150 cs4970 nextSibling mail lab1 firstChild lab2 proj1 proj.h coll.h coll.cpp

14

slide-15
SLIDE 15

another tree representations

class TreeNode { private: string element; vector<TreeNode *> children; public: ... }; // and more --- see when we talk about graphs

15

slide-16
SLIDE 16

tree traversal

/ × + 1 2

  • 3

4 × 5 6 pre-order: / * + 1 2 - 3 4 * 5 6 in-order: (((1+2) * (3-4)) / (5*6)) (parenthesis optional?) post-order: 1 2 + 3 4 - * 5 6 * /

16

slide-17
SLIDE 17

pre/post-order traversal printing

(this is pseudocode)

TreeNode::printPreOrder() { this−>print(); for each child c of this: c−>printPreOrder() } TreeNode::printPostOrder() { for each child c of this: c−>printPostOrder() this−>print(); }

17

slide-18
SLIDE 18

in-order traversal printing

(this is pseudocode)

BinaryTreeNode::printInOrder() { if (this−>left) this−>left−>printInOrder(); cout << this−>element << " ␣ "; if (this−>right) this−>right−>printInOrder(); }

18

slide-19
SLIDE 19

post-order traversal counting

(this is pseudocode)

int numNodes(TreeNode *tnode) { if ( tnode == NULL ) return 0; else { sum=0; for each child c of tnode sum += numNodes(c); return 1 + sum; } }

19

slide-20
SLIDE 20

expression tree and traversals

+ a * + b c d (a + ((b + c) * d))

20

slide-21
SLIDE 21

expression tree and traversals

+ a * + b c d infjx: (a + ((b + c) * d)) postfjx: a b c + d * + prefjx: + a * + b c d

21

slide-22
SLIDE 22

postfjx expression to tree

use a stack of trees number n → push( n )

  • perator OP →

pop into A, B; then push OP A B

22

slide-23
SLIDE 23

example

a b + c d e + * * top of stack a b + a b c d e c + d e * c + d e * + a b * c + d e

23

slide-24
SLIDE 24

example

a b + c d e + * * top of stack a b + a b c d e c + d e * c + d e * + a b * c + d e

23

slide-25
SLIDE 25

example

a b + c d e + * * top of stack a b + a b c d e c + d e * c + d e * + a b * c + d e

23

slide-26
SLIDE 26

example

a b + c d e + * * top of stack a b + a b c d e c + d e * c + d e * + a b * c + d e

23

slide-27
SLIDE 27

example

a b + c d e + * * top of stack a b + a b c d e c + d e * c + d e * + a b * c + d e

23

slide-28
SLIDE 28

example

a b + c d e + * * top of stack a b + a b c d e c + d e * c + d e * + a b * c + d e

23

slide-29
SLIDE 29

example

a b + c d e + * * top of stack a b + a b c d e c + d e * c + d e * + a b * c + d e

23

slide-30
SLIDE 30

binary trees

class BinaryNode { ... int element; BinaryNode *left; BinaryNode *right; };

all nodes have at most 2 children 1 2 3 4 5 6 7 1 2 4 5 3 6 7 element = 2 left = NULL right = addr of node 3 element = 7 left = NULL right = NULL

24

slide-31
SLIDE 31

binary trees

class BinaryNode { ... int element; BinaryNode *left; BinaryNode *right; };

all nodes have at most 2 children 1 2 3 4 5 6 7 1 2 4 5 3 6 7 element = 2 left = NULL right = addr of node 3 element = 7 left = NULL right = NULL

24

slide-32
SLIDE 32

binary trees

class BinaryNode { ... int element; BinaryNode *left; BinaryNode *right; };

all nodes have at most 2 children 1 2 3 4 5 6 7 1 2 4 5 3 6 7 element = 2 left = NULL right = addr of node 3 element = 7 left = NULL right = NULL

24

slide-33
SLIDE 33

binary search trees

binary tree and… each node has a key for each node:

keys in node’s left subtree are less than node’s keys in node’s right subtree are greater than node’s

4 2 1 3 5 7 6 8 left subtree of 4 right subtree of 4 right subtree of 5

25

slide-34
SLIDE 34

binary search trees

binary tree and… each node has a key for each node:

keys in node’s left subtree are less than node’s keys in node’s right subtree are greater than node’s

4 2 1 3 5 7 6 8 left subtree of 4 right subtree of 4 right subtree of 5

25

slide-35
SLIDE 35

binary search trees

binary tree and… each node has a key for each node:

keys in node’s left subtree are less than node’s keys in node’s right subtree are greater than node’s

4 2 1 3 5 7 6 8 left subtree of 4 right subtree of 4 right subtree of 5

25

slide-36
SLIDE 36

not a binary search tree

8 5 2 4 6 11 10 15 18 20 21

26

slide-37
SLIDE 37

binary search tree versus binary tree

binary search trees are a kind of binary tree …but — often people say “binary tree” to mean “binary search tree”

27

slide-38
SLIDE 38

BST: fjnd

(pseudocode)

find(node, key) { if (node == NULL) return NULL; else if (key < node−>key) return find(node−>left, key) else if (key > node−>key) return find(node−>right, key) else // if (key == node->key) return node; }

28

slide-39
SLIDE 39

BST: insert

(pseudocode)

insert(Node *&node, key) { if (node == NULL) node = new BinaryNode(key); else if (key < node−>key) insert(node−>left, key); else if (key < root−>key) insert(node−>right, key); else // if (key > root->key) ; // duplicate -- no new node needed }

29

slide-40
SLIDE 40

BST: fjndMin

(pseudocode)

findMin(Node *node, key) { if (node−>left == NULL) return node; else insert(node−>left, key); }

30

slide-41
SLIDE 41

BST: remove (1)

5 4 1 3 9 7 11 5 4 1 3 9 11 case 1: no children

31

slide-42
SLIDE 42

BST: remove (2)

5 4 1 3 9 7 11 5 4 3 9 7 11 case 2: one child

32

slide-43
SLIDE 43

BST: remove (3)

5 4 1 3 9 7 11 7 4 3 9 11 case 3: two children replace with minimum of right subtree (alternately: maximum of left subtree, …)

33

slide-44
SLIDE 44

binary tree: worst-case height

1 2 3 4 5 6 7 n-node BST: worst-case height/depth n − 1

34

slide-45
SLIDE 45

binary tree: best-case height

4 2 1 3 6 5 7 height h: at most 2h+1 − 1 nodes

35

slide-46
SLIDE 46

binary tree: proof best-case height is possible

proof by induction: can have 2h+1 − 1 nodes in h-height tree h = 0: h = 0: exactly one node; 2h+1 − 1 = 1 nodes h = k → h = k + 1: start with two copies of a maximum tree of height k create a new tree as follows:

create a new root node add edges from the root node to the roots of the copies

the height of this new tree is k + 1

path of length k in old tree + either new edge

the number of nodes is 2(2k+1 − 1) + 1 = 2k+1+1 − 2 + 1 = 2k+1+1 − 1

36

slide-47
SLIDE 47

binary tree: best-case height is best

(informally) property of trees in root:

except for the leaves, every node in tree has 2 children

no way to add nodes without increasing height

add below leaf — longer path to root — longer height add above root — every old node has longer path to root

37

slide-48
SLIDE 48

binary tree height formula

n: number of nodes h: height

n + 1 ≤ 2h+1 log2(n + 1) ≤ log2

  • 2h+1

log(n + 1) ≤ h + 1 h ≥ log2 (n + 1) − 1

shortest tree of n nodes: ∼ log2(n) height

38

slide-49
SLIDE 49

perfect binary trees

4 2 1 3 6 5 7

a binary tree is perfect if

all leaves have same depth all nodes have zero children (leaf) or two children

exactly the trees that achieve 2h+1 − 1 nodes

39

slide-50
SLIDE 50

AVL animation tool

http://webdiis.unizar.es/asignaturas/EDA/ AVLTree/avltree.html

40

slide-51
SLIDE 51

AVL tree idea

AVL trees: one of many balanced trees —

search tree balanced to keep height Θ(log n) avoid “tree is just a long linked list” scenarios

gaurentees Θ(log n) for fjnd, insert, remove AVL = Adelson-Velskii and Landis

41

slide-52
SLIDE 52

AVL gaurentee

the height of the left and right subtrees of every node difgers by at most one

42

slide-53
SLIDE 53

AVL state

normal binary search tree stufg:

data; and left, right, parent pointers

additional AVL stufg:

height of right subtree minus height of left subtree

called “balance factor”

  • 1, 0, +1

(kept up to date on insert/delete — computing on demand is too slow)

43

slide-54
SLIDE 54

example AVL tree

5 4 1 9 7 8 11

44

slide-55
SLIDE 55

example AVL tree

5 b: +1 4 b: -1 1 b: 0 9 b: -1 7 b: +1 8 b: 0 11 b: 0

44

slide-56
SLIDE 56

example non-AVL tree

5 b: -2 4 b: -3 1 b: +2 3 b: -1 2 b: 0 8 b: 0 7 b: 0 11 b: 0

45

slide-57
SLIDE 57

AVL tree algorithms

fjnd — exactly the same as binary search tree

just ignore balance factors

insert — two extra steps:

update balance factors “fjx” tree if it became unbalanced

runtime for both where is depth of node found/inserted

max balance factor at root max depth of node is

46

slide-58
SLIDE 58

AVL tree algorithms

fjnd — exactly the same as binary search tree

just ignore balance factors

insert — two extra steps:

update balance factors “fjx” tree if it became unbalanced

runtime for both Θ(d) where d is depth of node found/inserted

max balance factor ±1 at root max depth of node is Θ(log2 n + 1) = Θ(log n)

46

slide-59
SLIDE 59

AVL insertion cases

simple case: tree remains balanced

  • therwise:

let x be deepest imbalanced node (+2/-2 balance factor)

insert in left subtree of left child of x: single rotation right insert in right subtree of right child of x: single rotation left insert in right subtree of left child of x: double left-right rotation insert in left subtree of right child of x: double right-left rotation

47

slide-60
SLIDE 60

AVL: simple right rotation

just inserted 0 unbalanced root becomes new left child

3 b: -2 2 b: -1 1 b: 0 2 b: 0 1 b: 0 3 b: 0

48

slide-61
SLIDE 61

AVL: less simple right rotation (1)

just inserted 0 unbalanced root becomes new left child

5 b: -2 3 b: -1 2 b: -1 1 b: 0 4 b: 0 10 b: 0 3 b: 0 2 b: -1 1 b: 0 5 b: 0 4 b: 0 10 b: 0

49

slide-62
SLIDE 62

AVL: simple left rotation

just inserted 1 deepest unbalanced node is 3

1 b: +2 2 b: +1 3 b: 0 2 b: 0 1 b: 0 3 b: 0

50

slide-63
SLIDE 63

AVL rotation: up and down

at least one node moves up (this case: 1 and 2) at least one node moves down (this case: 3)

3 b: -2 2 b: -1 1 b: 0 2 b: 0 1 b: 0 3 b: 0

51

slide-64
SLIDE 64

AVL: less simple right rotation (2)

just inserted 1

15 b: -2 5 b: -2 3 b: -1 2 b: -1 1 b: 0 4 b: 0 10 b: 0 20 b: 0 17 b: 0 21 b: 0 15 b: -1 3 b: 0 2 b: -1 1 b: 0 5 b: 0 4 b: 0 10 b: 0 20 b: 0 17 b: 0 21 b: 0

deepest unbalanced subtree

52

slide-65
SLIDE 65

AVL: less simple right rotation (2)

just inserted 1

15 b: -2 5 b: -2 3 b: -1 2 b: -1 1 b: 0 4 b: 0 10 b: 0 20 b: 0 17 b: 0 21 b: 0 15 b: -1 3 b: 0 2 b: -1 1 b: 0 5 b: 0 4 b: 0 10 b: 0 20 b: 0 17 b: 0 21 b: 0

deepest unbalanced subtree

52

slide-66
SLIDE 66

AVL: less simple right rotation (2)

just inserted 1

15 b: -2 5 b: -2 3 b: -1 2 b: -1 1 b: 0 4 b: 0 10 b: 0 20 b: 0 17 b: 0 21 b: 0 15 b: -1 3 b: 0 2 b: -1 1 b: 0 5 b: 0 4 b: 0 10 b: 0 20 b: 0 17 b: 0 21 b: 0

deepest unbalanced subtree

52

slide-67
SLIDE 67

AVL: less simple right rotation (2)

just inserted 1

15 b: -2 5 b: -2 3 b: -1 2 b: -1 1 b: 0 4 b: 0 10 b: 0 20 b: 0 17 b: 0 21 b: 0 15 b: -1 3 b: 0 2 b: -1 1 b: 0 5 b: 0 4 b: 0 10 b: 0 20 b: 0 17 b: 0 21 b: 0

deepest unbalanced subtree

52

slide-68
SLIDE 68

general single rotation

a b X (h+1) Y (h) Z (h) b X (h+1) a Y (h) Z (h)

rotate right rotate left X < b < Y < a < Z

53

slide-69
SLIDE 69

double rotation

15 b: -2 8 b: -2 4 b: 1 3 b: 0 6 b: -1 5 b: 0 10 b: 0 17 b: -1 16 b: 0 15 b: -1 6 b: 0 4 b: 0 3 b: 0 5 b: 0 8 b: 1 10 b: 0 17 b: -1 16 b: 0

step 1: rotate subtree left step 2: rotate imbalanced tree right

8 b: 8 6 b: -1 4 b: -1 3 b: 0 5 b: 0 10 b: 0

54

slide-70
SLIDE 70

double rotation

15 b: -2 8 b: -2 4 b: 1 3 b: 0 6 b: -1 5 b: 0 10 b: 0 17 b: -1 16 b: 0 15 b: -1 6 b: 0 4 b: 0 3 b: 0 5 b: 0 8 b: 1 10 b: 0 17 b: -1 16 b: 0

step 1: rotate subtree left step 2: rotate imbalanced tree right

8 b: 8 6 b: -1 4 b: -1 3 b: 0 5 b: 0 10 b: 0

54

slide-71
SLIDE 71

double rotation

15 b: -2 8 b: -2 4 b: 1 3 b: 0 6 b: -1 5 b: 0 10 b: 0 17 b: -1 16 b: 0 15 b: -1 6 b: 0 4 b: 0 3 b: 0 5 b: 0 8 b: 1 10 b: 0 17 b: -1 16 b: 0

step 1: rotate subtree left step 2: rotate imbalanced tree right

8 b: 8 6 b: -1 4 b: -1 3 b: 0 5 b: 0 10 b: 0

54

slide-72
SLIDE 72

double rotation

15 b: -2 8 b: -2 4 b: 1 3 b: 0 6 b: -1 5 b: 0 10 b: 0 17 b: -1 16 b: 0 15 b: -1 6 b: 0 4 b: 0 3 b: 0 5 b: 0 8 b: 1 10 b: 0 17 b: -1 16 b: 0

step 1: rotate subtree left step 2: rotate imbalanced tree right

8 b: 8 6 b: -1 4 b: -1 3 b: 0 5 b: 0 10 b: 0

54

slide-73
SLIDE 73

general double rotation

a b W (h) c X (h) Y (h-1) Z (h) c b W (h) X (h) a Y (h-1) Z (h)

rotate W < b < X < c < Y < Z becomes root, so its children and both switch parents

55

slide-74
SLIDE 74

general double rotation

a b W (h) c X (h) Y (h-1) Z (h) c b W (h) X (h) a Y (h-1) Z (h)

rotate W < b < X < c < Y < Z c becomes root, so its children X and Y both switch parents

55

slide-75
SLIDE 75

double rotation names

sometimes “double left”

fjrst rotation left, or second?

us: “double left-right”

rotate child tree left rotate parent tree right

“double right-left”

rotate child tree right rotate parent tree left

56

slide-76
SLIDE 76

AVL insertion cases

simple case: tree remains balanced

  • therwise:

let x be deepest imbalanced node (+2/-2 balance factor)

insert in left subtree of left child of x: single rotation right insert in right subtree of right child of x: single rotation left insert in right subtree of left child of x: double left-right rotation insert in left subtree of right child of x: double right-left rotation

57

slide-77
SLIDE 77

AVL insert cases (revisited)

3 b: -2 2 b: -1 1 b: 0 1 b: +2 2 b: +1 3 b: 0 3 b: -2 1 b: +1 2 b: 0 1 b: +2 3 b: -1 2 b: 0

single left single right left-right right-left

choose rotation based on lowest imbalanced node and on direction of insertion (inserted node is green+dashed)

58

slide-78
SLIDE 78

AVL insert cases (revisited)

3 b: -2 2 b: -1 1 b: 0 1 b: +2 2 b: +1 3 b: 0 3 b: -2 1 b: +1 2 b: 0 1 b: +2 3 b: -1 2 b: 0

single left single right left-right right-left

choose rotation based on lowest imbalanced node and on direction of insertion (inserted node is green+dashed)

58

slide-79
SLIDE 79

AVL insert case: detail (1)

3 b: -2 2 b: -1 1 b: 0 7 b: -2 3 b: -2 2 b: -1 1 b: 0 9 b: 0

choose rotation based on lowest imbalanced node and on direction of insertion (inserted node is green+dashed)

59

slide-80
SLIDE 80

AVL insert case: detail (2)

3 b: -2 2 b: -1 b: 0 7 b: -2 4 b: -1 2 b: -1 1 b: -1 b: 0 3 b: 0 5 b: +1 6 b: 0 8 b: 0

choose using lowest imbalanced node and on direction of insertion (inserted node is green+dashed)

60

slide-81
SLIDE 81

61

slide-82
SLIDE 82

AVL tree: runtime

worst depth of node: Θ(log2 n + 2) = Θ(log n) fjnd: Θ(log n)

worst case: traverse from root to worst depth leaf

insert: Θ(log n)

worst case: traverse from root to worst depth leaf then back up (update balance factors) then perform constant time rotation

remove: Θ(log n)

left as exercise (similar to insert)

print: Θ(n)

visit each of n nodes

62

slide-83
SLIDE 83
  • ther types of trees

many kinds of balanced trees not all binary trees difgerent ways of tracking balance factors, etc. difgerent ways of doing tree rotations or equivalent

63

slide-84
SLIDE 84

red-black trees

each node is red or black null leafs considered nodes to aid analysis (still null pointers…) rules about when nodes can be red/black gaurentee maximum depth

13 8 1 n NULL 6 n NULL n NULL 11 n NULL n NULL 17 15 n NULL n NULL 25 22 n NULL n NULL 27 n NULL n NULL

64

slide-85
SLIDE 85

red-black tree rules

root is black counting null pointers as nodes, leaves are black a red node’s children are black

→ a red node’s parents are black

every simple path from node to leaf under it contains same number

  • f black nodes

(property holds regardless of whether null pointers are considered nodes)

65

slide-86
SLIDE 86

worst red-black tree imbalance

same number of black nodes on paths to leaves → factor of 2 imbalance max

A B D E C F H J K I L M G N O

66

slide-87
SLIDE 87

red-black insert

default: insert as red (no change to black node count), but… (1) if new node is root: color black (2) if parent is black: keep child red (3) if parent and uncle is red: adjust several colors (4) if parent is red, uncle is black, new node is right child

perform a rotation, then go to case 5

(5) if parent is red, uncle is black, new node is left child

perform a rotation

property: “root is black” no children no worries about # black nodes

  • n difgerent paths

property: “children of red node are black” no change in # of black nodes on paths

67

slide-88
SLIDE 88

red-black insert

default: insert as red (no change to black node count), but… (1) if new node is root: color black (2) if parent is black: keep child red (3) if parent and uncle is red: adjust several colors (4) if parent is red, uncle is black, new node is right child

perform a rotation, then go to case 5

(5) if parent is red, uncle is black, new node is left child

perform a rotation

property: “root is black” no children no worries about # black nodes

  • n difgerent paths

property: “children of red node are black” no change in # of black nodes on paths

68

slide-89
SLIDE 89

red-black insert

default: insert as red (no change to black node count), but… (1) if new node is root: color black (2) if parent is black: keep child red (3) if parent and uncle is red: adjust several colors (4) if parent is red, uncle is black, new node is right child

perform a rotation, then go to case 5

(5) if parent is red, uncle is black, new node is left child

perform a rotation

property: “root is black” no children no worries about # black nodes

  • n difgerent paths

property: “children of red node are black” no change in # of black nodes on paths

69

slide-90
SLIDE 90

case 3: parent, uncle are red

G P U N 1 2 3 4 5 G P U N 1 2 3 4 5

make grandparent red, parent and uncle black

(property: every path to leaf has same number of black nodes) just swapped grandparent and parent/uncle in those paths

but…what if grandparent’s parent is red?

(property: children of red node are black) solution: recurse to the grandparent, as if it was just inserted

image: Wikipedia/Abloomfj

70

slide-91
SLIDE 91

case 3: parent, uncle are red

G P U N 1 2 3 4 5 G P U N 1 2 3 4 5

make grandparent red, parent and uncle black

(property: every path to leaf has same number of black nodes) just swapped grandparent and parent/uncle in those paths

but…what if grandparent’s parent is red?

(property: children of red node are black) solution: recurse to the grandparent, as if it was just inserted

image: Wikipedia/Abloomfj

70

slide-92
SLIDE 92

case 3: parent, uncle are red

G P U N 1 2 3 4 5 G P U N 1 2 3 4 5

make grandparent red, parent and uncle black

(property: every path to leaf has same number of black nodes) just swapped grandparent and parent/uncle in those paths

but…what if grandparent’s parent is red?

(property: children of red node are black) solution: recurse to the grandparent, as if it was just inserted

image: Wikipedia/Abloomfj

70

slide-93
SLIDE 93

red-black insert

default: insert as red (no change to black node count), but… (1) if new node is root: color black (2) if parent is black: keep child red (3) if parent and uncle is red: adjust several colors (4) if parent is red, uncle is black, new node is right child

perform a rotation, then go to case 5

(5) if parent is red, uncle is black, new node is left child

perform a rotation

property: “root is black” no children no worries about # black nodes

  • n difgerent paths

property: “children of red node are black” no change in # of black nodes on paths

71

slide-94
SLIDE 94

case 4: parent red, uncle black, right child

G P U N 1 2 3 4 5 G U N P 1 2 3 4 5

perform left rotation on parent subtree and new node now case 5 (but new node is P, not N)

image: Wikipedia/Abloomfj

72

slide-95
SLIDE 95

red-black insert

default: insert as red (no change to black node count), but… (1) if new node is root: color black (2) if parent is black: keep child red (3) if parent and uncle is red: adjust several colors (4) if parent is red, uncle is black, new node is right child

perform a rotation, then go to case 5

(5) if parent is red, uncle is black, new node is left child

perform a rotation

property: “root is black” no children no worries about # black nodes

  • n difgerent paths

property: “children of red node are black” no change in # of black nodes on paths

73

slide-96
SLIDE 96

case 5: parent red, uncle black, left child

G P U N 1 2 3 4 5 G U P N 1 2 3 4 5

perform right rotation of grandparent and parent swap colors of parent and grandparent preserves properties:

red parent’s children are black every path to leaf has same number of black nodes

image: Wikipedia/Abloomfj

74

slide-97
SLIDE 97

example recursive case

100 10 3 1 5 8 15 200 10 3 1 5 8 100 15 200

initially: leaves are black red node’s children are black same number of black nodes in every path from node to leaves insert 8 initially make red case 3: parent, uncle are red

3 1 5 8

before: case 3: parent, uncle are red: grandparent becomes red parent/uncle black case 3 (parent, uncle are red) continued: recusively examine grandparent 3 case 5: parent (of 3) is red uncle is black, left child

100 10 3 … … 15 200

case 5: parent is red uncle is black, left child: perform right rotation

  • f parent + grandparent (of 3)

(and swap parent/grandparent colors)

75

slide-98
SLIDE 98

example recursive case

100 10 3 1 5 8 15 200 10 3 1 5 8 100 15 200

initially: leaves are black red node’s children are black same number of black nodes in every path from node to leaves insert 8 initially make red case 3: parent, uncle are red

3 1 5 8

before: case 3: parent, uncle are red: grandparent becomes red parent/uncle black case 3 (parent, uncle are red) continued: recusively examine grandparent 3 case 5: parent (of 3) is red uncle is black, left child

100 10 3 … … 15 200

case 5: parent is red uncle is black, left child: perform right rotation

  • f parent + grandparent (of 3)

(and swap parent/grandparent colors)

75

slide-99
SLIDE 99

example recursive case

100 10 3 1 5 8 15 200 10 3 1 5 8 100 15 200

initially: leaves are black red node’s children are black same number of black nodes in every path from node to leaves insert 8 initially make red case 3: parent, uncle are red

3 1 5 8

before: case 3: parent, uncle are red: grandparent becomes red parent/uncle black case 3 (parent, uncle are red) continued: recusively examine grandparent 3 case 5: parent (of 3) is red uncle is black, left child

100 10 3 … … 15 200

case 5: parent is red uncle is black, left child: perform right rotation

  • f parent + grandparent (of 3)

(and swap parent/grandparent colors)

75

slide-100
SLIDE 100

example recursive case

100 10 3 1 5 8 15 200 10 3 1 5 8 100 15 200

initially: leaves are black red node’s children are black same number of black nodes in every path from node to leaves insert 8 initially make red case 3: parent, uncle are red

3 1 5 8

before: case 3: parent, uncle are red: grandparent becomes red parent/uncle black case 3 (parent, uncle are red) continued: recusively examine grandparent 3 case 5: parent (of 3) is red uncle is black, left child

100 10 3 … … 15 200

case 5: parent is red uncle is black, left child: perform right rotation

  • f parent + grandparent (of 3)

(and swap parent/grandparent colors)

75

slide-101
SLIDE 101

example recursive case

100 10 3 1 5 8 15 200 10 3 1 5 8 100 15 200

initially: leaves are black red node’s children are black same number of black nodes in every path from node to leaves insert 8 initially make red case 3: parent, uncle are red

3 1 5 8

before: case 3: parent, uncle are red: grandparent becomes red parent/uncle black case 3 (parent, uncle are red) continued: recusively examine grandparent 3 case 5: parent (of 3) is red uncle is black, left child

100 10 3 … … 15 200

case 5: parent is red uncle is black, left child: perform right rotation

  • f parent + grandparent (of 3)

(and swap parent/grandparent colors)

75

slide-102
SLIDE 102

example recursive case

100 10 3 1 5 8 15 200 10 3 1 5 8 100 15 200

initially: leaves are black red node’s children are black same number of black nodes in every path from node to leaves insert 8 initially make red case 3: parent, uncle are red

3 1 5 8

before: case 3: parent, uncle are red: grandparent becomes red parent/uncle black case 3 (parent, uncle are red) continued: recusively examine grandparent 3 case 5: parent (of 3) is red uncle is black, left child

100 10 3 … … 15 200

case 5: parent is red uncle is black, left child: perform right rotation

  • f parent + grandparent (of 3)

(and swap parent/grandparent colors)

75

slide-103
SLIDE 103

RB-tree: removal

start with normal BST remove of x, but… instead fjnd next highest/lowest node y

can choose node with at most one child (“bottom” of a left or right subtree)

swap x and y’s value, then replace y with its child several cases for color maintainence/rotations

76

slide-104
SLIDE 104

RB tree: removal cases

N: node just replaced with child; S: its sibling; P: its parent (1): N is new root (2): S is red (3): P, S, and S’s children are black (4): S and S’s children are black (5): S is black, S’s left child is red, S’s right child is black, N is left child of P (6): S is black, S’s right child is red, N is left child details: see, e.g., Wikipedia article

77

slide-105
SLIDE 105

why red-black trees?

a lot more cases…but a lot less rotations …because tree is kept less rigidly balanced red-black trees end up being faster in practice

78

slide-106
SLIDE 106

more balanced trees

several other kinds of balanced trees

  • ne notable kind: non-binary balanced trees

commonly used in databases

more effjcient to store multiple nodes together on disk/SSD

79

slide-107
SLIDE 107

splay trees

tree that’s fast for recently used nodes self-balancing binary search tree keeps recent nodes near the top simpler to implement than AVL or RB trees

80

slide-108
SLIDE 108

‘splaying’

every time node is accessed (fjnd, insert, delete)… “splay” tree around that node make the node the new tree root time — where is tree height

worst-case height: — linked-list case

81

slide-109
SLIDE 109

‘splaying’

every time node is accessed (fjnd, insert, delete)… “splay” tree around that node make the node the new tree root Θ(h) time — where h is tree height

worst-case height: — linked-list case

81

slide-110
SLIDE 110

‘splaying’

every time node is accessed (fjnd, insert, delete)… “splay” tree around that node make the node the new tree root Θ(h) time — where h is tree height

worst-case height: Θ(n) — linked-list case

81

slide-111
SLIDE 111

splay tree operations

3 2 1 4 3 2 1 2 1 3 4

insert 4 fjnd 2

82

slide-112
SLIDE 112

amortized complexity

splay tree insert/fjnd/delete is amortized O(log n) time informally: average insert/fjnd/delete: O(log n) more formally: m operations: O(m log n) time (where n: max size

  • f tree)

83

slide-113
SLIDE 113

splay tree pro/con

can be faster than AVL, RB-trees in practice

take advantage of frequently accessed items

simpler to implement but worst case fjnd/insert is Θ(n) time

84

slide-114
SLIDE 114

last time

red-black trees

less well-balanced than AVL trees track color instead of balance factor rules about colors to limit possible imbalance algorithm for insertion, etc. that makes tree always obey rules usually faster in practice — less rotations

splay trees

  • ptimized for repeated accesses

keep recently accessed items near top of tree fjnd rearranges tree! amortized logarithmic time (but worst case is linear)

85

slide-115
SLIDE 115

amortized analysis: vector growth

vector insert algorithm:

if not big enough, double capacity write to end of vector

doubling size — requires copying! — time worst case per insert but average…?

86

slide-116
SLIDE 116

amortized analysis: vector growth

vector insert algorithm:

if not big enough, double capacity write to end of vector

doubling size — requires copying! — Θ(n) time Θ(n) worst case per insert but average…?

86

slide-117
SLIDE 117

counting copies (1)

suppose initial capacity 100 + insert 1600 elements

100 → 200: 100 copies 200 → 400: 200 copies 400 → 800: 400 copies 800 → 1600: 800 copies total: 1500 copies

total operations: 1500 copies + 1600 writes of new elements

about 2 operations per insert

87

slide-118
SLIDE 118

counting copies (2)

more generally: for N inserts about N copies + N writes

why? K to 2K elements: K copies N inserts: 1 + 2 + 4 + . . . + N/4 + N/2 = N − 1 copies (and a bit better if initial capacity isn’t 1)

worst case but time for inserts amortized time per insert

88

slide-119
SLIDE 119

counting copies (2)

more generally: for N inserts about N copies + N writes

why? K to 2K elements: K copies N inserts: 1 + 2 + 4 + . . . + N/4 + N/2 = N − 1 copies (and a bit better if initial capacity isn’t 1)

Θ(n) worst case but Θ(n) time for n inserts → O(1) amortized time per insert

88

slide-120
SLIDE 120
  • ther vector capacity increases? (1)

instead of doubling…add 1000 N inserts: 1000 + 2000 + 3000 + . . . + N ∼ N2 → Θ(N2) total — O(N) amortized time per insert increase by constant: linear worst-case and amortized

89

slide-121
SLIDE 121
  • ther vector capacity increases? (1)

instead of doubling…add 1000 N inserts: 1000 + 2000 + 3000 + . . . + N ∼ N2 → Θ(N2) total — O(N) amortized time per insert increase by constant: linear worst-case and amortized

89

slide-122
SLIDE 122

instead of doubling…multiply by k > 1

e.g. k = 1.1 — increase by 10%

inserts: total — amortized time per insert amortized constant time for all

90

slide-123
SLIDE 123

instead of doubling…multiply by k > 1

e.g. k = 1.1 — increase by 10%

N inserts: 1 + k + k2 + k3 + . . . + klogk N = 1 − klogk N 1 − k ∼ N total — amortized time per insert amortized constant time for all

90

slide-124
SLIDE 124

instead of doubling…multiply by k > 1

e.g. k = 1.1 — increase by 10%

N inserts: 1 + k + k2 + k3 + . . . + klogk N = 1 − klogk N 1 − k ∼ N → Θ(N) total — O(1) amortized time per insert amortized constant time for all k > 1

90

slide-125
SLIDE 125

trees are not great for…

  • rdered, unsorted lists

list of TODO tasks

being easy/simple to implement

compare, e.g., stack/queue

Θ(1) time

compare vector compare hashtables (almost)

91

slide-126
SLIDE 126

programs as trees

int z; int foo (int x) { for (int y = 0; y < x; y++) cout << y << endl; } int main() { int z = 5; cout << "enter x" << endl; cin >> z; foo(z); }

program vars int z functions foo() params int z vars body for int y y < x y++ body cout y endl main() params vars int z =5 body cout "enter z" endl cin z foo() z

92

slide-127
SLIDE 127

programs as trees

int z; int foo (int x) { for (int y = 0; y < x; y++) cout << y << endl; } int main() { int z = 5; cout << "enter x" << endl; cin >> z; foo(z); }

program vars int z functions foo() params int z vars body for int y y < x y++ body cout y endl main() params vars int z =5 body cout "enter z" endl cin z foo() z

92

slide-128
SLIDE 128

abstract syntax tree

program vars int z functions foo() params int z vars body for int y y < x y++ body cout y endl main() params vars int z =5 body cout "enter z" endl cin z foo() z

for loop: four children init, condition, update, body

class ASTNode { ... }; // public class ForNode extends ASTNode class ForNode : public ASTNode { ... private: ASTNode *init, *condition, *update, *body; }; 93

slide-129
SLIDE 129

abstract syntax tree

program vars int z functions foo() params int z vars body for int y y < x y++ body cout y endl main() params vars int z =5 body cout "enter z" endl cin z foo() z

for loop: four children init, condition, update, body

class ASTNode { ... }; // public class ForNode extends ASTNode class ForNode : public ASTNode { ... private: ASTNode *init, *condition, *update, *body; }; 93

slide-130
SLIDE 130

abstract syntax tree

program vars int z functions foo() params int z vars body for int y y < x y++ body cout y endl main() params vars int z =5 body cout "enter z" endl cin z foo() z

for loop: four children init, condition, update, body

class ASTNode { ... }; // public class ForNode extends ASTNode class ForNode : public ASTNode { ... private: ASTNode *init, *condition, *update, *body; }; 93

slide-131
SLIDE 131

AST applications

“abstract syntax tree” = “parse tree” part of how compilers work do some tree traversal to do…

code generation — e.g. ASTNode::outputCode() method

  • ptimization

type checking…

94

slide-132
SLIDE 132

using AST to compare programs

comparing trees is a good way to compare programs… while ignoring:

function/method order (e.g. sort function nodes by length) variable names (e.g. ignore variable names when comparing) comments …

part of many software plagerism/copy+paste detection tools

95