1 Trees CLRS: chapter 12
2 A hierarchical combinatorial structure הגדרה רקורסיבית: 1. צומת בודד. זהו גם שורש העץ. 2. אם n הוא צומת ו T 1 ….T K הינם עצים, ניתן לבנות עץ חדש שבו n השורש ו T 1 ….T K הינם “תתי עצים”. T1T1 TKTK n T1T1 TKTK n...
3 r c1c1 c2c2 c3c3 s 1.1 s 1.2 s 1.3 s 2.1 s 2.2 s 3.1 מושגים: r - הורה/Parent (אבא) של c1, c2, c3 c 1, c 2 - ילדים/children של r s צאצא/Descendant (לא ישיר) של r r,c 1,s מסלול/Path (אם כ”א הורה של הקודם) אורך המסלול = מס’ הקשתות = מס’ הצמתים (פחות אחד) צומת ללא ילדים = עלה/Leaf r - אב קדמון/Ancestor של s 3.1 Terminology
גובה העץ - אורך המסלול הארוך ביותר מהשורש לעלה (height) עומק צומת - אורך המסלול מהצומת לשורש (depth) Ordered tree יש משמעות לסדר הילדים. מסדרים משמאל לימין. a bC a Cb אם הסדר לא חשוב - עץ לא מסודר (unordered tree)
- עץ ריק או לכל צומת יש תת קבוצה של {ילד ימני, ילד שמאלי} דוגמא: עצים בינאריים Full : each internal node always has both children
6 The dictionary problem Maintain (distinct) items with keys from a totally ordered universe subject to the following operations E.g.: 5, 19, 2, 989, 7 ( = order )
7 The ADT Insert(x,D) Delete(x,D) Find(x,D): Returns a pointer to x if x ∊ D, and a pointer to the successor or predecessor of x if x is not in D ( worth to add an indicator if found or not ) Order not important
8 The ADT successor(x,D) predecessor(x,D) Min(D) (2) Max(D) (989) Order Operation s D= {5, 2, 7, 19, 989}
9 The ADT catenate(D 1,D 2 ) : Assume all items in D 1 are smaller than all items in D 2 split(x,D) : Separate to D 1, D 2. D 1 with all items smaller than x and D 2 with all items greater than x D= {5, 2, 7, 19, 989} D1= {5, 2, 7} {19, 989}
10 Reminder from “mavo” We have seen solutions using unordered lists and ordered lists. Worst case running time O(n) We also defined Binary Search Trees (BST)
11 Binary search trees A representation of a set with keys from a totally ordered universe We put each element in a node of a binary tree subject to:
12 BST If y is in the left subtree of x then y.key < x.key If y is in the right subtree of x then y.key > x.key
13 BST x.right x.key x.left x x.parent
14 Y ← null z ← T.root While z ≠ null do y ← z if x = z.key return z if x < z.key then z ← z.left else z ← z.right return y Find(x,T) Return pointer to where element should be (this is why we have y
15 Y ← null z ← T.root While z ≠ null do y ← z if x = z.key return z if x < z.key then z ← z.left else z ← z.right return y Find(5,T) z Return pointer to where element should be
16 Y ← null z ← T.root While z ≠ null do y ← z if x = z.key return z if x < z.key then z ← z.left else z ← z.right return y Find(5,T) z y Return pointer to where element should be
17 Y ← null z ← T.root While z ≠ null do y ← z if x = z.key return z if x < z.key then z ← z.left else z ← z.right return y Find(5,T) z y Return pointer to where element should be
18 Y ← null z ← T.root While z ≠ null do y ← z if x = z.key return z if x < z.key then z ← z.left else z ← z.right return y Find(5,T) z y Return pointer to where element should be
19 Y ← null z ← T.root While z ≠ null do y ← z if x = z.key return z if x < z.key then z ← z.left else z ← z.right return y Find(5,T) z y Return pointer to where element should be
20 Y ← null z ← T.root While z ≠ null do y ← z if x = z.key return z if x < z.key then z ← z.left else z ← z.right return y Find(5,T) z y Return pointer to where element should be
21 Y ← null z ← T.root While z ≠ null do y ← z if x = z.key return z if x < z.key then z ← z.left else z ← z.right return y Find(6,T) z y Return pointer to where element should be (this case predecessor of 6)
22 Y ← null z ← T.root While z ≠ null do y ← z if x = z.key return z if x < z.key then z ← z.left else z ← z.right return y Find(6,T) y z=null Return pointer to where element should be (this case predecessor of 6)
Min(T) 6 Min(T.root) min(z): While (z.left ≠ null) do z ← z.left return (z) 1.5
24 n ← new node n.key ← x n.left ← n.right ← null y ← find(x,T) n.parent ← y if x < y.key then y.left ← n else y.right ← n Insert(x,T)
Insert(6,T) n ← new node n.key ← x n.left ← n.right ← null y ← find(x,T) n.parent ← y if x < y.key then y.left ← n else if x > y.key y.right ← n else (x= y.key) do nothing To avoid duplicates: must check if element is there
Insert(6,T) 6 y n ← new node n.key ← x n.left ← n.right ← null y ← find(x,T) n.parent ← y if x < y.key then y.left ← n else y.right ← n
Delete(6,T) 6 If node has < 2 children: take father(node) and make it point to child(node) (Node is leaf or has one child)
Delete(6,T) If node has < 2 children: take father(node) and make point to child(node)
Delete(8,T) If node has < 2 children: take father(node) and make point to child(node)
Delete(8,T) If node has < 2 children: take father(node) and make point to child(node)
Delete(2,T) 6 Switch 5 and 2 and delete the node containing now 2 If node has < 2 children: take father(node) and make point to child(node)
Delete(2,T) 6 Switch 5 and 2 and delete the node containing 5
33 delete(x,T) q ← find(x,T) If q.left = null or q.right = null then z ← q else z ← min(q.right) q.key ← z.key q Find z that does not have 2 children! Z is physical deletion point Why minimum? Minimum never has 2 children
34 delete(x,T) q ← find(x,T) If q.left = null or q.right = null then z ← q else z ← min(q.right) q.key ← z.key q z Find z that does not have 2 children! Z is physical deletion point
35 delete(x,T) q ← find(x,T) If q.left = null or q.right = null then z ← q else z ← min(q.right) q.key ← z.key q Find z that does not have 2 children! Z is physical deletion point
36 delete(x,T) q ← find(x,T) If q.left = null or q.right = null then z ← q else z ← min(q.right) q.key ← z.key q z Find z that does not have 2 children! Z is physical deletion point Z has at most one child now!
37 delete(x,T) q ← find(x,T) If q.left = null or q.right = null then z ← q else z ← min(q.right) q.key ← z.key If z.left ≠ null then y ← z.left else y ← z.right z Z is physical deletion point
38 delete(x,T) q ← find(x,T) If q.left = null or q.right = null then z ← q else z ← min(q.right) q.key ← z.key If z.left ≠ null then y ← z.left else y ← z.right z y
39 delete(x,T) q ← find(x,T) If q.left = null or q.right = null then z ← q else z ← min(q.right) q.key ← z.key If z.left ≠ null then y ← z.left else y ← z.right If y ≠ null then y.parent ← z.parent z y
40 delete(x,T) q ← find(x,T) If q.left = null or q.right = null then z ← q else z ← min(q.right) q.key ← z.key If z.left ≠ null then y ← z.left else y ← z.right If y ≠ null then y.parent ← z.parent p = z.parent If z = p.left then p.left = y else p.right = y z y p
41 delete(x,T) q ← find(x,T) If q.left = null or q.right = null then z ← q else z ← min(q.right) q.key ← z.key If z.left ≠ null then y ← z.left else y ← z.right If y ≠ null then y.parent ← z.parent p = z.parent If z = p.left then p.left = y else p.right = y z y p
42 delete(x,T) q ← find(x,T) If q.left = null or q.right = null then z ← q else z ← min(q.right) q.key ← z.key If z.left ≠ null then y ← z.left else y ← z.right If y ≠ null then y.parent ← z.parent p = z.parent If z = p.left then p.left = y else p.right = y
43 Variation: Items only at the leaves Keep elements only at the leaves Each internal node contains a number to direct the search Implementation is simpler (e.g. delete) Costs space
44 Analysis Each operation takes O(h) time, where h is the height of the tree In general h may be as large as n Want to keep the tree with small h
45 Balance h = O(log n) How do we keep the tree balanced through insertions and deletions ?
46 1) O(n) : Worst Case 2) כמה זמן לוקח בממוצע (תוחלת) להכניס n איברים אקראיים? עץ מושלם: עץ קווי: כל איבר לוקח לכל היותר log n O(n) לצומת ממוצע: צריך להניח הנחות - רק INSERT - כל הסדרים שווי הסתברות (סדרים בין n אלמנטים) Data Structures, CS, TAU אנליזת זמן של עץ חיפוש בינארי
47 - רוצים לחשב אורך מסלול ממוצע: קח את האיבר הראשון (a) ההסתברות שi איברים קטנים ממנו היא a iN-i-1 יהי L(n) אורך ממוצע של מסלול של צומת שרירותי בעץ בגודל n (אורך מסלול כאן = מס’ צמתים במסלול) אזי, אם i איברים קטנים מ- a, האורך הממוצע הוא: שמאל ימין מרכז (j=n-i-1) Data Structures, CS, TAU - 5.7
48 נוריד את ההתניה על i: הצב: נראה באינדוקציה: הוכחה: Data Structures, CS, TAU - 5.8
49 Data Structures, CS, TAU - 5.9
50 Balance h = O(log n) How do we keep the tree balanced through insertions and deletions ? - Next chapter!
successor(x,T) 6 1.5
52 successor(x,T) If x has a right child it’s the minimum in the subtree of x.right x
successor(6,T) 6 1.5
54 successor(x,T) If x.right is null, go up until the lowest ancestor such that x is at its left subtree x
55 successor(x,T) If x.right ≠ null then min(x.right) y ← x.parent While y≠null and x=y.right do x ← y y ← y.parent return(y) x
56 successor(x,T) If x.right ≠ null then min(x.right) y ← x.parent While y≠null and x=y.right do x ← y y ← y.parent return(y) y x
57 successor(x,T) If x.right ≠ null then min(x.right) y ← x.parent While y≠null and x=y.right do x ← y y ← y.parent return(y) y x
58 successor(x,T) If x.right ≠ null then min(x.right) y ← x.parent While y≠null and x=y.right do x ← y y ← y.parent return(y) y x