Tirgul 13:Trees
1
הגדרות
– מודל מופשט של מבנה היררכי. עץ מורכב עץ•מאוסף של צמתים )קודקודים( עם יחס אבא-בן.
– צומת ללא אבא. בכל עץ יש בדיוק בעץשורש•שורש אחד. לכל הצמתים פרט לשורש יש בדיוק אב
אחד. 2
הגדרות
הנו Y, ו Y של צומת אב קדמון הינו Xצומת • עובר Y אם המסלול מהשורש אל X של צאצא
.Xדרך X אם X של בן הנו W, ו W של אבא הנו הXצומת •
ויש ביניהם צלעWהנו אב קדמון של
Y
X
W
3
הגדרות
– צומת אשר אין לו בנים.עלה•
= מרחק הצומת של צומת בעץ עומק•מהשורש.
4
הגדרות – עומק מקסימאלי של צומת של העץ גובה•
(.1-בעץ )וגובה של עץ ריק הוא
עץ אשר בו מספר הבנים של - עץ בינארי•.2כל צומת אינו עולה על
5
הגדרותעץ חיפוש בינארי
עץ בינארי אשר בו עבור כל צומת, הערכים של כל האיברים בתת העץ השמאלי שלו
קטנים )או שווים( ממנו, וכל האיברים .בתת העץ הימני שלו גדולים ממנו
6
77
77
11
33 1010
44
66 1414
1313
שלוש שיטות לסריקת עץ
pre-order, in-order ,post-order.
בביצוע הסריקות בעץ הנתון יתקבל סדר האיברים הבא:
: (pre-order )תחילי•:(in-order)תוכי •: (post-order )סופי•
11
99
88
66 33
22
55
7
1,6,8,5,2,9,38,6,2,5,9,1,3
8,2,9,5,6,3,1
מה הייתה התוצאה אם binary searchהעץ היה
tree?
הגדרות: עוקב וקודם
:x לצומת העוקב
הצומת בעל מפתח הקטן x ביותר הגדול מערך של
:x לצומתהקודם
הוא הצומת בעל מפתח הגדול ביותר הקטן מערך
x של
דוגמה:
הואWהקודם של
הואWהעוקב של
הואCהקודם של
הואCהעוקב של
:inOrder, לפי סריקת BSTב- R
8
Y
B
E
דוגמא
9
מימוש: עץ
10
public class BinaryTree {
protected BinaryNode root;
public BinaryTree)( {root = null;
} // BinaryTree
public boolean isEmpty)( {return root == null;
} // isEmpty public void insert)Object toAdd( {
if )isEmpty)(( root = new BinaryNode)toAdd(;else root.insert)toAdd(;
} // insert
public String inOrder)( {if )isEmpty)(( return "";else return root.inOrder)(;
} // inOrder public String preOrder)( {
if )isEmpty)(( return "";else return root.preOrder)(;
} // preOrder
public String postOrder)( {if )isEmpty)(( return "";else return root.postOrder)(;
} // postOrder}
BinaryTree
11
BinaryNode
public class BinaryNode { protected Object data; protected BinaryNode left; protected BinaryNode right;
public BinaryNode)Object data( {this.data = data;left = null;right = null;
} // BinaryNode …}
public void insert)Object toAdd( { double select = Math.random)(; if )select > 0.5( {
if )left == null( left = new BinaryNode)toAdd(;else left.insert)toAdd(;
} else {
if )right == null( right = new BinaryNode)toAdd(;else right.insert)toAdd(;
}} // insert
12
BinaryNode
public String inOrder)( { String res = ""; if )left != null(
res = res + left.inOrder)(; if )data == null(
res = res + " <null> "; else
res = res + " " + data.toString)( + " "; if )right != null(
res = res + right.inOrder)(; return res;} // inOrder
public String preOrder)( { String res = ""; if )data == null(
res = res + " <null> "; else
res = res + " " + data.toString)( + " "; if )left != null(
res = res + left.preOrder)(; if )right != null(
res = res + right.preOrder)(; return res;} // preOrder
13
BinaryNode
14
public String postOrder)( { String res = ""; if )left != null(
res = res + left.postOrder)(; if )right != null(
res = res + right.postOrder)(; if )data == null(
res = res + " <null> "; else
res = res + " " + data.toString)( + " "; return res;} // postOrder
דוגמה לשיטות של עצים: בעץ בינארי כלליגובהחישוב
:BinaryTreeבמחלקה
public int height)( { if )isEmpty)((
return -1; else
return root.height)(;} // height
:BinaryNodeבמחלקה
public int height)( { int resLeft = -1; int resRight = -1; if )left != null( {
resLeft = left.height)(; } if )right != null( {
resRight = right.height)(; } return Math.max)resLeft, resRight( + 1;} // height
15
מימוש:חיפוש בינארי - עץ
BST
BST
BinaryTree
BSN
BinaryNode
הורשה
16
BST
17
import java.util.Comparator;public class BST extends BinaryTree { private Comparator comp;
public BST)Comparator comp( {super)(;this.comp = comp;
} // BST
… // )override insert only(
} // class BST
public class BSN extends BinaryNode { private Comparator comp;
public BSN)Object data, Comparator comp( {
super)data(;this.comp = comp;
} // BSN
… // )override insert, remove, etc.(} // class BSN
import java.util.Comparator;
public class Main {
public static void main)String[] args( {
Comparator comp = new IntegerComparator)(;
BST tree1 = new BST)comp(;
tree1.insert)new Integer)50((; // Step 1
tree1.insert)new Integer)60((; // Step 2
tree1.insert)new Integer)40((; // Step 3
tree1.insert)new Integer)30((; // Step 4
tree1.insert)new Integer)20((; // Step 5
tree1.insert)new Integer)45((; // Step 6
tree1.insert)new Integer)65((; // Step 7
System.out.println)"InOrder: " + tree1.inOrder)((;
System.out.println)"PreOrder: " + tree1.preOrder)((;
System.out.println)"PostOrder: " + tree1.postOrder)((;
System.out.println)"Find Minimum: " + tree1.findMin)((;
System.out.println)"Height: " + tree1.height)((;
}
} 18
50
6040
30
20
45 65
Step 1Step 2Step 3Step 4Step 5Step 6Step 7
public class IntegerComparator implements Comparator {public int compare)Object o1, Object o2( {
if )))Integer(o1(.intValue)( > ))Integer(o2(.intValue)((return 1;
else if )))Integer(o1(.intValue)( == ))Integer(o2(.intValue)((return 0;
elsereturn -1;
}}
IntegerComparator
19
public class CharacterComparator implements Comparator {public int compare)Object o1, Object o2( {
if )))Character(o1(.charValue)( > ))Character(o2(.charValue)((return 1;
else if )))Character(o1(.charValue)( == ))Character(o2(.charValue)((return 0;
elsereturn -1;
}}
CharacterComparator
20
BST Insert: Example
• Example: Insert C
F
B H
KDA
C
21
הכנסה איבר חדש לעץ
:BSTבמחלקה
public void insert)Object toAdd({ if )isEmpty)(( {
root = new BSN)toAdd, this.comp(; } else { root.insert)toAdd(; }} // insert
:BSNבמחלקה
public void insert)Object toAdd( { if )comp.compare)toAdd, this.data( < 0( { if )left == null( left = new BSN)toAdd,this.comp(; else left.insert)toAdd(; } if )comp.compare)toAdd, this.data( > 0( { if )right == null( right = new BSN)toAdd,this.comp(; else right.insert)toAdd(; }} // insert
22
מציאת קודקוד בעל מפתח מינימאלי.בעץ חיפוש בינארי
:BSTבמחלקה public Object findMin)( {
if )isEmpty)(( {return null; // Exceptions are needed...
}return ))BSN(root(.findMin)(;
} // findMin:BSNבמחלקה
public Object findMin)( {BinaryNode t=this;while) t.left != null (
t = t.left;return t.data;
} // findMin
23
מה היינו צריכים לעשות אם ?BSTהעץ לא היה
דוגמא ממבחן
24
) FULL ( עץ בינארי מלא
עץ בינארי אשר בו לכל צומת מלאעץ בינארי .פנימי יש )בדיוק( שני בנים
25
) PERFECT ( עץ בינארי מושלם
עץ בינארי מלא שבו לכל .העלים יש אותו עומק
מושלםעץ בינארי
26
) COMPLETE ( עץ בינארי שלם
לכל הקדקודים שלו עד
h-2h-2 שכבה
בנים2 יש בדיוק
כל הקדקודים
hhברמה ה
מרוכזים לשמאל
שלםעץ בינארי ומתקיים: h שגובהו עץ בינארי
27
בדיקה האם עץ בינארי הוא עץ בינארי מושלם
:BSTבמחלקה public boolean isPerfect)( {
return ))BSN(root(.isPerfect)(;}
:BSNבמחלקה public boolean isPerfect)( {
int h = height)(; //class method if )h==0( return true; if )h==1( return )!)left==null( && !)right==null((; return )!)left==null( && )left.height)( == h - 1( &&
))BSN(left(.isPerfect)( && !)right==null( &&)right.height)( == h - 1( && ))BSN(right(.isPerfect)((;}
עץ בינארי מושלם
28
"שלם"בדיקה האם עץ בינארי הוא שלםראינו את ההגדרות הבאות:עץ בינארי
עץ בינארי מלא שבו לכל העלים אותו עומק- (perfect)עץ מושלם
ומתקייםhעץ בינארי שגובהו (complete )עץ בינארי שלם
h-2לכל הקדקודים שלו עד שכבה
בנים2יש בדיוק
hכל הקדקודים ברמה ה מרוכזים לשמאל
שלםעץ בינארי
29
בהגדרה רקורסיבית
הוא ריקאו
הבן השמאלי שלו הוא שורש של עץ h-1 בגובה שלם
והבן הימני שלו הוא שורש של עץ h-2בגובה מושלם
אוהבן השמאלי שלו הוא שורש של עץ
h-1בגובה מושלם והבן הימני שלו הוא שורש של עץ
h-1 בגובה שלם
אם ורק אם:שלם הוא hעץ בינארי בגובה
30
1 או 0אנחנו נבדוק כמה מקרי קצה כי אם גובה העץ הוא 1 או –0נקבל שדרוש לבדוק אם גובה תת העץ הוא
:BSTבמחלקה public boolean isComplete)( {
return ))BSN(root(.isComplete)(;}
:BSNבמחלקה public boolean isComplete)( { int h = height)(; //class method if )h==0( return true; if )h==1( return )!)left==null((; //the height is 2 and up: boolean has2Sons = )!)left==null( && !)right==null((; boolean case1=false, case2=false; if )has2Sons( { int leftH = left.height)(; int rightH = right.height)(; case1 = )))leftH == h-1( && ))BSN(left(.isComplete)(( && )rightH == h-2( && ))BSN(right(.isPerfect)((; case2 = )))leftH == h-1( && ))BSN(left(.isPerfect )(( && )rightH == h-1( && ))BSN(right(.isComplete)((; } return case1 || case2;}
שלםעץ בינארי
31
סמסטר ב' מועד ב'2006מבחן 1 שאלה
סעיף א•( הינה עץ בינארי ובו המפתח בכל heapערימה )
קודקוד גדול )כפי שמוגדר על ידי הממשק Comparable .מהמפתחות בילדיו )
דוגמא – העץ להלן מהווה ערימה חוקית אך אם ילד שמאלי עם 7נוסיף לקודקוד בעל המפתח
נקבל עץ שאינו מהווה ערימה חוקית9מפתח
בכל הסעיפים בשאלה זו ניתן להניח כי אין בעץ •.nullמפתחות בעלי ערך
זהות למחלקות HeapNode ו- Heapהמחלקות •BinaryTree-ו BinaryNode כפי שנלמדו בכיתה
( ושיטות גישה constructorsומכילות בנאים )(accessors.בהן ניתן להשתמש מבלי לממשן )
8
73
621
33
Heap למחלקות getKeysInRangeהוסיפו את השיטה HeapNodeו-
השיטה מחזירה רשימה משורשרת המכילה את כל המפתחות . ]cFirst, cLast[בתחום הסגור
לדוגמא – הקריאה• getKeysInRange) new Integer)3( , new Integer)8( (
על הערימה למעלה תחזיר רשימה המכילה את המפתחות )לא בהכרח בסדר זה(. 67,,8,3
8
73
621
34
public class Heap{private HeapNode mRoot;public LinkedList getKeysInRange) Comparable cFirst,
Comparable cLast ({// Complete here
}}
public class HeapNode{private Comparable mKey;private HeapNode mLeft, mRight;public void getKeysInRange) Comparable cFirst,
Comparable cLast, LinkedList lKeys ({
// Complete here}
} 35
In Heap class:public LinkedList getKeysInRange) Comparable cFirst,
Comparable cLast ( {LinkedList lKeys = new LinkedList)(;if) mRoot != null ( mRoot.getKeysInRange)cFirst,cLast,lKeys(;return lKeys;
}
36
In HeapNode class:public void getKeysInRange) Comparable cFirst,
Comparable cLast,LinkedList lKeys ( {
if) mData.compareTo) cFirst ( >= 0 ({if) mData.compareTo) cLast ( <= 0 && mData.compareTo) cFirst ( >= 0 ( lKeys.add)mData (;if) mLeft != null ( mLeft.getKeysInRange)cFirst,cLast, lKeys(;if) mRight != null (
mRight.getKeysInRange)cFirst,cLast, lKeys(;}
}
37