Menu
Coddy logo textTech

Binary Search Tree (עץ חיפוש בינארי)

עודכן לאחרונה

עץ חיפוש בינארי שומר את הערכים שלו בסדר ממוין: לכל צומת, כל הערכים בתת העץ השמאלי שלו קטנים ממנו וכל הערכים בתת העץ הימני שלו גדולים ממנו. כדי להכניס או למצוא ערך מתחילים בשורש ופונים שוב ושוב שמאלה או ימינה לפי ההשוואה, כך שכל צעד חוצה את מרחב החיפוש. לחצו על הפעלה למעלה כדי לראות ערכים מוצבים לפי השוואה וחיפוש שיורד לאורך העץ.

בעץ מאוזן הפעולות האלה רצות בזמן O(log n). המלכודת: הכנסת נתונים שכבר ממוינים הופכת את העץ לרשימה מקושרת עם פעולות O(n), ובדיוק בגלל זה קיימים עצים שמאזנים את עצמם כמו AVL ועצים אדומים-שחורים.

סיבוכיות זמן וזיכרון

פעולהמאוזןהמקרה הגרוע (עקום)
חיפושO(log n)O(n)
הכנסהO(log n)O(n)
מחיקהO(log n)O(n)
זיכרוןO(n)O(n)

צעד אחר צעד (הכנסה)

צעדמה קורה
1אם העץ ריק, הערך החדש הופך לשורש.
2אחרת מתחילים בשורש.
3אם הערך קטן יותר, עוברים לבן השמאלי; אם גדול יותר, פונים ימינה.
4חוזרים על כך עד שמגיעים למקום ריק.
5מחברים שם את הערך החדש כעלה.

דוגמה מפורטת

הכנסת [5, 3, 8, 1, 4] לעץ ריק, ערך אחד בכל פעם:

הכנסההמסלול שנבחרפעולה
5-העץ ריק, ולכן 5 הופך לשורש.
353 < 5, פונים שמאלה; המקום ריק, מחברים את 3 כבן השמאלי של 5.
858 > 5, פונים ימינה; המקום ריק, מחברים את 8 כבן הימני של 5.
15 -> 31 < 5 פונים שמאלה, ואז 1 < 3 פונים שמאלה; מחברים את 1 כבן השמאלי של 3.
45 -> 34 < 5 פונים שמאלה, ואז 4 > 3 פונים ימינה; מחברים את 4 כבן הימני של 3.

מתי להשתמש בעץ חיפוש בינארי

השתמשו בו כאשרהימנעו ממנו כאשר
אתם צריכים סדר ממוין וגם חיפושים מהירים, וההכנסות מגיעות בסדר אקראי.הנתונים מגיעים כבר ממוינים: BST לא מאוזן מידרדר ל-O(n) לכל פעולה.
אתם רוצים שמעבר in-order יחזיר את הערכים ברצף ממוין בלי עלות נוספת.אתם צריכים רק בדיקות שייכות בלי סדר: טבלת גיבוב נותנת חיפוש של O(1) בממוצע.
אתם צריכים שאילתות טווח או את העוקב והקודם של מפתח.אתם צריכים חסמים מובטחים של O(log n): בחרו במקום זאת עץ AVL או עץ אדום-שחור שמאזנים את עצמם.
הנתונים משתנים לעתים קרובות ועדכון מערך ממוין סטטי היה יקר.הנתונים קבועים ולקריאה בלבד: מערך ממוין עם חיפוש בינארי פשוט יותר וידידותי למטמון.

קוד Binary Search Tree

מימוש נקי של Binary Search Tree שאפשר להריץ, ב-Python, JavaScript, Java, C++, C. בחרו שפה, העתיקו את הקוד, או פתחו אותו טעון מראש בעורך האונליין של Coddy.

קוד Binary Search Tree ב-Python

Python
1class Node:2    def __init__(self, key):3        self.key = key4        self.left = None5        self.right = None6
7
8def insert(node, key):9    if node is None:10        return Node(key)11    if key < node.key:12        node.left = insert(node.left, key)13    elif key > node.key:14        node.right = insert(node.right, key)15    return node  # duplicates are ignored16
17
18def search(node, key):19    if node is None:20        return False21    if key == node.key:22        return True23    if key < node.key:24        return search(node.left, key)25    return search(node.right, key)26
27
28def inorder(node):29    if node is None:30        return []31    return inorder(node.left) + [node.key] + inorder(node.right)32
33
34root = None35for key in [8, 3, 10, 1, 6, 14, 4, 7]:36    root = insert(root, key)37
38print("Inorder (sorted):", inorder(root))39print("search(6): ", search(root, 6))40print("search(5): ", search(root, 5))
להריץ את הקוד הזה בעורך ה-Python אונליין

שאלות נפוצות על עץ חיפוש בינארי

מהי סיבוכיות הזמן של עץ חיפוש בינארי?
חיפוש, הכנסה ומחיקה הם O(log n) בעץ מאוזן, כי כל השוואה זורקת חצי מהצמתים שנותרו. במקרה הגרוע, עץ שהפך לשרשרת עקומה בגלל הכנסות ממוינות, הם מידרדרים ל-O(n).
מה ההבדל בין עץ בינארי לעץ חיפוש בינארי?
עץ בינארי הוא כל עץ שבו לכל צומת יש לכל היותר שני ילדים, בלי כלל סדר. עץ חיפוש בינארי מוסיף את השמורה שערכי תת העץ השמאלי קטנים מהצומת וערכי תת העץ הימני גדולים ממנו, וזה מה שמאפשר חיפוש מהיר.
למה עץ חיפוש בינארי יכול להפוך לאיטי?
אם הערכים מוכנסים בסדר ממוין (או בסדר ממוין הפוך), כל צומת חדש הולך לאותו צד, ונוצר עץ גבוה ועקום שמתנהג כמו רשימה מקושרת: O(n) לכל פעולה. עצים שמאזנים את עצמם (AVL, אדום-שחור) מסובבים צמתים כדי למנוע את זה.
מה ההבדל בין עץ חיפוש בינארי לטבלת גיבוב?
טבלת גיבוב נותנת חיפוש של O(1) בממוצע, אבל שומרת את המפתחות בלי סדר מסוים, ולכן היא לא יכולה לענות על שאילתות טווח או עוקב. עץ חיפוש בינארי איטי מעט יותר, O(log n), אבל שומר את המפתחות מסודרים, כך שאפשר לעבור עליהם בסדר ממוין ולמצוא ערכים קרובים. בחרו ב-BST כשהסדר חשוב, ובטבלת גיבוב כשצריך רק בדיקות שייכות.
מתי כדאי להשתמש בעץ שמאזן את עצמו במקום ב-BST רגיל?
השתמשו בעץ שמאזן את עצמו (AVL, אדום-שחור) בכל פעם שאין לכם שליטה על סדר ההכנסה ואתם צריכים ביצועים מובטחים של O(log n). BST רגיל מתאים ללימוד, לכמויות נתונים קטנות, או כשהמפתחות מגיעים בסדר אקראי, אבל הוא לא מציע שום הגנה מפני המקרה הגרוע העקום.
האם מעבר in-order על BST מחזיר ערכים ממוינים?
כן. ביקור בתת העץ השמאלי, אחר כך בצומת ואז בתת העץ הימני מחזיר את המפתחות בסדר עולה, וזה נובע ישירות מהשמורה של BST. טעות נפוצה היא לצפות לאותו דבר מעץ בינארי רגיל: בלי כלל הסדר, מעבר in-order לא מייצר רצף בעל משמעות.
איור של שפות התכנות ב-Coddy

לשלוט באלגוריתמים עם Coddy

להתחיל