תרגול 13
עצים
U
U
U
הגדרות:
עץ – מבנה נתונים של קודקודים )צמתים( וקשתות כך שלכל קודקוד יש אב יחיד ,פרט לקודקוד השורש )שלו
אין אבא(.
U
צומת Xהוא אב קדמון של צומת ,Yו Yהנו צאצא של Xאם המסלול מהשורש אל Yעובר דרך .X
צומת Xהוא האבא של ,Yו Yהנו הבן של Xאם Xהנו אב קדמון של Yויש ביניהם צלע.
עלה – צומת אשר אין לו בנים.
צומת פנימי – צומת אשר אינו עלה.
עומק – מרחק הצומת מהשורש.
גובה – המרחק המקסימאלי של צומת מעלה )בתת העץ שלו(.
עץ בינארי
עץ אשר בו מספר הבנים של כל צומת אינו עולה על .2
עץ חיפוש בינארי
עץ בינארי אשר בו עבור כל צומת הערכים של כל האיברים
בתת העץ השמאלי שלו קטנים )או שווים( ממנו,
וכל האיברים בתת העץ הימני שלו גדולים ממנו.
שלוש שיטות לסריקת עץ ).(pre, in & post
עקוב אחר שלוש הסריקות בעץ הנתון ורשום מהו סדר
האיברים הנסרקים בכל אחת מהן.
תשובה:
תחילי ):(pre-order
תוכי ):(in-order
סופי ):(post-order
U
U
1,6,8,5,2,9,3
8,6,2,5,9,1,3
8,2,9,5,6,3,1
:מימוש
U
public class BinaryTree {
U
U
protected BinaryNode root;
U
U
public BinaryTree() {
root = null;
} // BinaryTree
U
U
public boolean isEmpty() {
return root == null;
} // isEmpty
U
U
public void insert(Object toAdd) {
if (isEmpty())
root = new BinaryNode(toAdd);
else
root.insert(toAdd);
} // insert
U
U
U
U
U
U
public String inOrder() {
if (isEmpty())
return "";
else
return root.inOrder();
} // inOrder
U
U
public String preOrder() {
if (isEmpty())
return "";
else return root.preOrder();
} // preOrder
U
U
public String postOrder() {
if (isEmpty())
return "";
else
return root.postOrder();
} // postOrder
} // class BinaryTree
U
U
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
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
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
} // class BinaryNode
import java.util.Comparator;
public class BST extends BinaryTree
{
private Comparator comp;
public BST(Comparator comp) {
super();
this.comp = comp;
} // BST
…
// (override insert, remove, etc.)
} // 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
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;
else
return -1;
}
}
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
tree1.insert(new
tree1.insert(new
tree1.insert(new
tree1.insert(new
tree1.insert(new
tree1.insert(new
Integer(50));
Integer(60));
Integer(40));
Integer(30));
Integer(20));
Integer(45));
Integer(65));
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());
System.out.println("Is Perfect?: " + tree1.isPerfect());
System.out.println("Is Complete? " + tree1.isComplete());
}
}
.חישוב גובה בעץ חיפוש בינארי
: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
.מציאת קודקוד בעל מפתח מינימאלי בעץ חיפוש בינארי
: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
:הכנסת איבר חדש לעץ
: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
עוקב וקודם
העוקב לצומת Xהוא הצומת בעל מפתח הקטן ביותר הגדול מהערך של X
הקודם לצומת הוא הצומת בעל מפתח הגדול ביותר הקטן מערך של X
הקודם של ,R – Wהעוקב של .Y – W
הקודם של ,B – Cהעוקב של .E – C
עץ בינארי מלא )(FULL
עץ בינארי אשר בו לכל צומת פנימי יש )בדיוק( שני בנים.
דוגמא
(COMPLETE) עץ בינארי שלם
: ומתקייםh עץ בינארי שגובהו
. בנים2 יש בדיוקh-2 • לכל הקודקודים שלו עד שכבה
. מרוכזים לשמאלh-• כל הקודקודים ברמה ה
(PERFECT) עץ בינארי מושלם
.עץ בינארי מלא שבו לכל העלים יש אותו עומק
בדיקה האם עץ בינארי הוא עץ בינארי מושלם:דוגמא
: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());
}
U
U
בדיקה האם עץ בינארי הוא עץ בינארי שלם
ראינו את ההגדרות הבאות:
עץ מושלם ) :(perfectעץ בינארי מלא שבו לכל העלים אותו עומק
עץ בינארי שלם ) :(completeעץ בינארי שגובהו hומתקיים
• כל הקדקודים שלו עד שכבה h-2יש בדיוק 2בנים.
• כל הקודקודים ברמה ה h-מרוכזים לשמאל.
בהגדרה רקורסיבית:
עץ בינארי הוא שלם אם ורק אם ) hהוא גובה העץ(
.1הוא ריק
או
.2הבן השמאלי שלו הוא שורש של עץ שלם בגובה h-1והבן הימני שלו הוא שורש של עץ מושלם בגובה
h-2
או
.3הבן השמאלי שלו הוא שורש של עץ מושלם בגובה h-1והבן הימני שלו הוא שורש של עץ שלם
בגובה h-1
אנחנו נבדוק כמה מקרי קצה כי אם גובה העץ הוא 0או 1נקבל שדרוש לבדוק אם גובה תת העץ הוא 0או :1
במחלקה :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
}
© Copyright 2025