תרגול 5 - עצים Tree, BST עצי חיפוש בינאריים
עץ Tree עץ מבנה נתונים המורכב מאוסף של צמתים וקשתות עם יחס היררכי )הורה-ילד(. )קדקודים( כל צומת מורכבת מנתונים שמאוחסנים בה, לילדים של הצומת. שורש הורה ילד ומאוסף של מצביעים אבות קדמונים של d צאצאים של b
עץ Tree עץ מבנה נתונים המורכב מאוסף של צמתים וקשתות עם יחס היררכי )הורה-ילד(. )קדקודים( כל צומת מורכבת מנתונים שמאוחסנים בה, לילדים של הצומת. ומאוסף של מצביעים צמתים פנימיים עלים
עץ Tree עץ מבנה נתונים המורכב מאוסף של צמתים וקשתות עם יחס היררכי )הורה-ילד(. )קדקודים( כל צומת מורכבת מנתונים שמאוחסנים בה, לילדים של הצומת. ומאוסף של מצביעים גובה של עץ הוא גובה של השורש גובה של - b המסלול הארוך ביותר בתת העץ של b עומק של f אורך המסלול מ f לשורש
עץ K Tree K לכל קודקוד יש k בנים לכל היותר.
עץ בינארי Tree Binary עץ בינארי מלא עץ אשר לכל קודקוד יש בדיוק 0 או 2 ילדים. עץ בינארי מלא עם n עלים מכיל 1 n קודקודים פנימיים. עץ בינארי שלם עץ בינארי שגובהו h ומתקיים: לכל הקודקודים שלו עד שכבה 2 h יש בדיוק 2 בנים. כל הקודקודים ברמה ה- h מרוכזים לשמאל. עץ בינארי מושלם בגובה h מכיל בין 2 h ל h+1 1 2 קודקודים. גובה של עץ בינארי מושלם עם n קודקודים הוא. log n עץ בינארי מושלם - כל הרמות מלאות.
עץ בינארי Binary Tree עץ בינארי עץ שבו לכל צומת יש לכל היותר שני ילדים )ימני ושמאלי(. סריקות של עץ בינארי pre-order שורש, תת עץ שמאלי, תת עץ ימני תת עץ שמאלי, שורש, תת עץ ימני in-order תת עץ שמאלי, תת עץ ימני, שורש post-order
Question 1 Solution: From pre-order we can see that a is the root. Given this, from post-order we can divide nodes into left sub-tree [c,d,b] and right sub-tree [h,g,j,e,f].
Question 1
Question 2? post-order האם ניתן לשחזר עץ בהנתן סריקות pre-order ו post-order: b,a תשובה: דוגמא: לא תמיד. pre-order: a,b a a שני העצים אפשריים או b b
לעץ בינארי T נגדיר L(T) מספר העלים בעץ T מספר הקדקודים בT D 2 (T) הוכיחו שבכל עץ בינארי עם דרגה 2( 2 T עם n אינטואיציה: כל קודקוד עם דרגה 1 לא מוסיף עלים. כל קודקוד עם דרגה 2 מוסיף פיצול בעץ שמוביל לעוד עלה. ילדים בדיוק( קדקודים מתקיים D 2 (T)=L(T)-1 Question 3 T פתרון: הוכחה באינדוקציה על מספר הקודקודים בעץ. מקרה בסיס:,n=1 D 2 (T)=0,L(T)=1 D 2 (T) = 7 L(T)= 8 D 2 (T) = 3 L(T)= 4 עלה אחד, D 2 (T) = 0 - כאשר נוצר קדקד עם שני בנים בשרשרת, שרשרת זה מוביל לעלה נוסף D 2 (T) = 1, L(T) = 2
T Question 3 פתרון: הוכחה באינדוקציה על מספר הקודקודים בעץ. מקרה בסיס:,n=1 D 2 (T)=0,L(T)=1 צעד האינדוקציה: נניח שהטענה נכונה לכל k<n נסתכל על השורש בעץ עם n קדקודים 2 מקרים אפשריים: מקרה ראשון: דרגת השורש היא 1. 1. ל T ול T 1 יש אותו מספר עלים 2. ל T ול T 1 יש אותו מספר קודקודים עם דרגה 2 D 2 (T) = D 2 (T 1 ) = L(T 1 ) 1 = L(T) 1 הנחת 2 1 האינדוקציה T 1
Question 3 צעד האינדוקציה: נניח שהטענה נכונה לכל k<n נסתכל על השורש בעץ עם n קדקודים 2 מקרים אפשריים: מקרה שני: דרגת השורש היא 2. מספר העלים ב T הוא סכום העלים ב T 1 וב T 2 1. מספר הקדוקים עם דרגה 2 ב T הוא סכום הקדקודים 2. ועוד קדקוד 1 )השורש( עם דרגה 2 ב T 1 ו ב T 2 ע"פ 2 T 1 D 2 T = D 2 T 1 + D 2 T 2 + 1 T 2 = L T 1 1 + L T 2 1 + 1 = L(T) 1 ע"פ ע"פ הנחת האינדוקציה 1
n עץ בינארי עם T הבאים: קודקודים. x קודקוד לכל Question 4 x.key מספר טבעי x.left מצביע לבן השמאלי x.right מצביע לבן הימני x.val מספר טבעי לשימוש כללי )אינו בשימוש בT יש את השדות במקור( נגדיר את maxpath(t) כסכום המקסימלי של מפתחות במסלול )פשוט( מהשורש לעלה כלשהו. נגדיר Path(T) כמסלול כלשהו עם סכום זה. דוגמא: maxpath(t)=23 Path(T) = left, left תארו אלגוריתם למציאת הערך maxpath(t) בזמן O(n) כיצד ניתן לשנות את האלגוריתם כך שגם ידפיס את המסלול המקסימלי? (a (b
Question 4 O(n) בזמן maxpath(t) תארו אלגוריתם למציאת הערך a) b) כיצד ניתן לשנות את האלגוריתם כך שגם ידפיס את המסלול המקסימלי? פתרון: a) מחשבים רקורסיבית את maxpath של הבן השאמלי וכן את maxpath של הבן הימני, ומוסיפים את המפתח של הקדקוד למקסימלי מבינם maxpath( T ){ if (T == null) return 0 lmax = maxpath(left-sub-tree(t)) rmax = maxpath(right-sub-tree(t)) m = Max(lmax, rmax) return m + T.key }
23,L 22,L 4 maxpath( T ){ if (T == null) return 0; lmax = maxpath(left-sub-tree(t)) rmax = maxpath(right-sub-tree(t)) m = Max(lmax, rmax) if (m == lmax) T.val = 0 else T.val = 1 return m + T.key } תרגיל 4 O(n) בזמן maxpath(t) תארו אלגוריתם למציאת הערך a) 15,L b) כיצד ניתן לשנות את האלגוריתם כך שגם ידפיס את המסלול 20 המקסימלי? 3 0 פתרון: b) נחשב את maxpath כמו קודם, רק שנעדכן את x.val ל 0 אם הסכום המקסימלי בא מתת-עץ השמאלי ו 1 אם מהשמאלי. בהדפסת המסלול נשתמש בערך x.val להחליט לאיזה כיוון להמשיך. PrintPath(T){ While (T.left null or T.right null ) if (T.val == 0) print("left ") T = T.left else print("right ") T = T.right }
תרגיל 4 O(n) בזמן maxpath(t) תארו אלגוריתם למציאת הערך a) b) כיצד ניתן לשנות את האלגוריתם כך שגם ידפיס את המסלול המקסימלי? ניתוח זמן: O(n) מבקרים בכל קדקוד פעם אחת, לכן זמן הריצה a) b) מבקרים פעם אחת בכל קדקוד במסלול, ומספר הקדקודים במסלול חסום ע"י n. לכן סה"כ O(n)
עץ חיפוש בינארי Binary Search Tree החל מהשורש, שמאלה עד הסוף החל מהשורש, ימינה עד הסוף
עץ חיפוש בינארי Binary Search Tree החל מהשורש, שמאלה עד הסוף החל מהשורש, ימינה עד הסוף החל מהצומת x, ימינה פעם אחת, ואז שמאלה עד הסוף דוגמא: = 24 20) (T, Successor או למעלה עד שיש פעם אחת "למעלה ימינה" דוגמא: = 30 28) (T, Successor
עץ חיפוש בינארי Binary Search Tree החל מהשורש, שמאלה עד הסוף החל מהשורש, ימינה עד הסוף החל מהצומת x, ימינה פעם אחת, ואז שמאלה עד הסוף דוגמא: = 24 20) (T, Successor או למעלה עד שיש פעם אחת "למעלה ימינה" דוגמא: = 30 28) (T, Successor החל מהצומת x, שמאלה פעם אחת, ואז ימינה עד הסוף דוגמא: = 28 30) (T, Predecessor או למעלה עד שיש פעם אחת "למעלה שמאלה" דוגמא: = 20 24) (T, Predecessor
Binary Search Tree עץ חיפוש בינארי Delete Delete node x from a BST T: If x is a leaf and the left child of his parent x.parent.left = null If x is a leaf and the right child of his parent x.parent.right = null If x has only one child, update x.parent to point to x's child instead of x. update the parent of the child of x to be the former parent of x If x has 2 children, replace x in node y, it's successor (y has no left son) Note that y might have right son. If so, then apply the same process of deleting a node with only one child to y.(see previous section)
Binary Search Tree עץ חיפוש בינארי הדגמת מחיקות מעץ חיפוש בינארי: 15 8 20 3 12 23 10 13 11
Binary Search Tree עץ חיפוש בינארי הדגמת מחיקות מעץ חיפוש בינארי: 15 8 20 3 12 23 10 13 11
תרגיל 5 נתון T BST בגודל n, בו לכל קדקוד x יש שדה נוסף של x.size מספר המפתחות )גודל( של תת-העץ של x )כולל x עצמו( הציעו אלגוריתם בזמן O(h) )כאשר h גובה העץ( למימוש מציאת מספר המפתחות שממש גדולים מk Greater(T,k) הדגמא: key=4 size= 11 key=8 size= 20 key=15 size= 36 key=10 size= 8 k = 10 Greater(T,k)=15+1+4=20 כל תת-העץ key=20 size= 15 כל תת-העץ הקדקוד key=12 size= 4
תרגיל 5 נתון T BST בגודל n, בו לכל קדקוד x יש שדה נוסף של x.size מספר המפתחות )גודל( של תת-העץ של x )כולל x עצמו( הציעו אלגוריתם בזמן O(h) )כאשר h גובה העץ( למימוש מציאת מספר המפתחות שממש גדולים מk Greater(T,k) Greater(T, k) keys = 0 while (T!= Null ) if (k < T.key) keys keys + T.right.size + 1 T = T.left else if (k > T.key) T = T.right {*} else // k = T.key keys keys + T.right.size break; return keys פתרון: זמן ריצה: O(h) הערה: h=o(n) במקרה הגרוע ביותר, ו( O(logn במקרה הממוצע
תרגיל 6 נתון עץ חיפוש בינארי T עם גובה h שמכיל קדקוד עם ערך a וקדקוד עם ערך b. מצאו אלגוריתם שמחזיר את כל המפתחות בטווח [a,b] )a<b( בזמן,O(h+k) כאשר k מספר המפתחות בטווח. את מי נחזיר עבור [42,55]? את מי נחזיר עבור [62,64]? x את מי נחזיר עבור [25,41]? a b נחפש את אחד הקדקודים a או, b וכאשר נמצא קדקוד ראשון בחיפוש שיהיה בטווח,[a,b] נסמנו x. For every node v in search path from a to x do: if (a v){ print v; inorder(v.right); } For every node v in search path from x to b do: if (b v){ inorder(v.left); print v;
6 תרגיל : פתרון Range(a, b) 1. 2. 3. 4. Find nodes containing a and b in the tree, let Pa and Pb be the search path from the root to a and b respectively. Let x be the node where Pa and Pb split. For every node v in the search path from a to x do: if (a < v){ print v; inorder(v.right); } For every node v in the search path from x to b do: if (b > v){ inorder(v.left); x print v; } 𝑃𝑎 𝑃𝑏 b a
תרגיל 7 נתונים שני עצי חיפוש בינאריים T 1 ו T 2 עם גבהים h 1 ו h 2 בהתאמה ( 1 h ו h 2 נתונים(. נתון בנוסף שכל הערכים ב T 1 קטנים ממש מכל הערכים ב T. 2 הניחו שכל ערכי המפתחות שונים. כיצד ניתן לאחד את שני העצים לעץ אחד המכיל את איחוד הערכים בזמן?O(max(h 1,h 2 )) כך שגובה עץ האיחוד יהיה,O(min(h 1,h 2 )) מה יהיה גובה עץ האיחוד? T 1 T 2.1.2
תרגיל 7 1. כיצד ניתן לאחד את שני העצים לעץ אחד המכיל את איחוד הערכים בזמן (( 2,O(min(h 1 h, כך שגובה עץ האיחוד יהיה?O(max(h 1,h 2 )) פתרון: case a: h 1 h 2 Extract from T 1 the element v with the maximum key in T 1 in O(h 1 ) time. v.left T 1 v.right T 2 v is the root of the new merged tree. T 1 T 2 max(t 1 )
תרגיל 7 1. כיצד ניתן לאחד את שני העצים לעץ אחד המכיל את איחוד הערכים בזמן (( 2,O(min(h 1 h, כך שגובה עץ האיחוד יהיה?O(max(h 1,h 2 )) פתרון: case a: h 1 h 2 Extract from T 1 the element v with the maximum key in T 1 in O(h 1 ) time. v.left T 1 v.right T 2 v is the root of the new merged tree. case b: h 1 > h 2 Extract from T 2 the element v with the minimum key in T 2 in O(h 2 ) time. v.left T 1 v.right T 2 v is the root of the new merged tree. T 1 T 2 min(t 2 ) 2. מה יהיה גובה עץ האיחוד? פתרון: )+1 2 max(h 1,h
תרגיל 8 מצאו אלגוריתם הבודק אם עץ בינארי נתון.BST הוא T הניחו שכל הערכים הינם מספרים שלמים שונים זה מזה הניחו שלכל קדקוד יש מצביע לשני הילדים אך לא מצביע להורה. פתרון )שגוי(: נבדוק בכל קדקוד בצורה רקורסיבית שערך הבן השמאלי קטן יותר מהערך הנוכחי וערך הבן הימני גדול יותר מהערך הנוכחי. פתרון זה אינו מספיק מצאו דוגמא נגדית 15 8 20 פתרון )מתוקן(: נשתמש בפונקציית עזר ששומרת את הגבולות העליונים והתחתונים של הערכים המורשים בתת-העץ. זמן הריצה הינו.O(n).O(n) פתרון אפשרי נוסף הוא ביצוע הליכת Inorder ובדיקה שהיא ממוינת. זמן ריצה
תרגיל 8 פתרון )מתוקן(: נשתמש בפונקציית עזר ששומרת את הגבולות העליונים והתחתונים של הערכים המורשים בתת-העץ boolean isvalid(node root) { return isvalidhelper(root, Integer.MIN_VALUE, Integer.MAX_VALUE) } boolean isvalidhelper(node curr, int min, int max) { if(curr.value < min curr.value > max) return false if (curr.left!= null &&!isvalidhelper(curr.left, min, curr.value)) return false if (curr.right!= null &&!isvalidhelper(curr.right, curr.value, max)) return false return true } זמן הריצה הינו.O(n) פתרון אפשרי נוסף הוא ביצוע הליכת Inorder ובדיקה שהיא ממוינת. ריצה.O(n) זמן