ערימה בינומית

במדעי המחשב, ערימה בינומית היא סוג של מבנה הנתונים ערימה. היא ממומשת בעזרת אוסף עצים בינומים. יתרונה הוא שהיא מאפשרת מיזוג שתי ערימות במהירות.

ערימה בינומית מהווה מימוש יעיל של מבנה הנתונים המופשט תור עדיפויות.

==מבנה==
ערימה בינומית ממומשת כאוסף של עצים בינומיים. כל עץ בינומי מקיים את "כלל הערימה": ערך כל צומת קטן יותר מערכי כל בניו (ערימה כזאת נקראת "ערימת מינימום". ניתן גם לבנות "ערימת מקסימום", בה כל צומת גדול מבניו).

=== תכונת הערימה הבינומית ===
ערימה בינומית מקיימת את השמורה הבאה: לכל i, יש בערימה לכל היותר עץ אחד מדרגה i.

דרגה של עץ בינומי מוגדרת על ידי מס' הצמתים בעץ, כך שעץ מדרגה 0 הוא שורש בלבד, ובעץ מדרגה i יש <math>2^i</math> קודקודים.

כתוצאה מכך יש מבנה אפשרי יחיד לערימה, הנובע מהייצוג הבינארי של גודלה. (לדוגמה, בערימה מגודל 25 (11001 בבסיס בינארי) יהיה עץ אחד מדרגה 0, עץ אחד מדרגה 3 ועץ אחד מדרגה 4). את שורשי העצים ניתן להחזיק ברשימה מקושרת כפולה (כלומר עם מצביעים אחורה).

== מאפיינים ==
בערימה בינומית יש לכל היותר עץ אחד מכל דרגה. לפיכך, בערימה בינומית בה דרגת העץ המקסימלי היא i יש לכל היותר 2^(i+1) איברים. לפיכך, בערימה בינומית בה יש m איברים- יש לכל היותר <math>\log m</math> עצים.

==פעולות==
מיזוג שתי ערימות
הפעולה המעניינת והחשובה ביותר בערימה בינומית היא מיזוג:

===== מיזוג =====
בהינתן שתי ערימות, ממזגים אותן בדומה לחיבור בינארי: עוברים על הדרגות מהקטנה לגדולה, ובכל דרגה, אם יש רק עץ אחד מדרגה כזו מכניסים לערימה המאוחדת. אם יש שניים, מאחדים אותם ומתייחסים אליהם כאל עץ מדרגה גדולה יותר (בדומה לנשא בחיבור רגיל). כיוון שישנם כ-log m עצים בכל ערימה, הסיבוכיות היא <math>O(\log m)</math>.

כעת נבחן כיצד לממש את שאר פעולות הערימה באמצעות פעולות המיזוג:

===== הכנסה =====
כדי להכניס אלמנט חדש, נבנה ערימה חדשה מדרגה 1 ונמזג אותה עם הערימה הקיימת.

סיבוכיות הפעולה היא <math>O(\log m)</math> (כש-m הוא גודל הערימה), אך ניתוח לשיעורין מביא לתוצאה של <math>O(1)</math>. (ומכאן שבניית ערימה מ-m איברים לוקחת <math>O(m)</math>)

===== מחיקת המינימום =====
הואיל וכל אחד משורשי העצים בערימה מקיים את תכונת הערימה, הרי שאיבר המינימום בערימה הוא אחד משורשי העצים. הואיל ובערימה בת m איברים יש log m שורשי עצים, ניתן למצוא את שורש המינימום ב- O(log m). מוצאים את איבר המינימום ומוחקים אותו. (ניתן, כשיפור, להחזיק מצביע לאיבר המינימלי, כך שמציאתו לוקחת <math>O(1)</math>.)

כיוון שילדיו של עץ מדרגה i הם שורשים של עצים מדרגות i-1,...,0,1, ניתן להסתכל על שורשיו כערימה בינומית מסדר i-1. כעת מבצעים מיזוג בין הערימה החדשה הזו לשאר הערימה. סיבוכיות: <math>O(\log m)</math>.

===== מחיקה =====
כיוון שערימה אינה תומכת בחיפוש, מחיקה צריכה לבוא עם מצביע לאיבר הנמחק. כדי למחוק מחליפים את ערך הצומת עם אביו, ואז שוב עד לשורש (פעולה זאת לוקחת כעומק המקסימלי של עץ שהוא כ-log m), ואז מוחקים אותו וממזגים את בניו עם שאר הערימה. סיבוכיות: <math>O(\log m)</math>.

===== הקטנת מפתח =====
בהינתן מצביע לצומת מסוים, מקטינים את המפתח, ואם הוא קטן מאביו, מחליפים ביניהם, ושוב אם הוא קטן מאביו מחליפים ביניהם עד שהוא גדול מאביו (או מגיע לשורש), סיבוכיות: <math>O (\log m)</math>. שיפור בסיבוכיות של פעולה זו אפשרי על ידי שימוש בערימת פיבונאצ'י, המבוססת על ערמה בינומית, בה עלות הקטנת מפתח בניתוח לשיעורין היא <math>O (1)</math>.

==וריאציות==
===ערימה בינומית עצלה===
ערימה בינומית עצלה ממומשת בדומה לערמה, אך היא לא משמרת את המבנה כל הזמן: בפעולות הכנסה ומיזוג פשוט משרשרים את האיבר החדש או הערימה החדשה לקיימת (ב-<math>O(1)</math>) ואילו בפעולת המחיקה מתקנים תוך כדי את הערימה לערימה בינומית תקינה, פעולה זאת לוקחת <math>O(n)</math>, אך בניתוח לשיעורין עלותה הוא <math>O(\log n)</math>.

===ערימת פיבונאצ'י===
בערימת פיבונאצ'י העצים כלל אינם עצים בינומיים: בכל פעולת הקטנת הערך חותכים את הצומת ויוצרים ממנו עץ חדש, וכאשר מוחקים כך שני בנים של צומת חותכים גם אותו. כתוצאה מכך העלות של פעולת הקטנת המפתח עולה ל-<math>O(n)</math>, אך עלותה לשיעורין יורדת ל-<math>O(1)</math>. בשל כך היא טובה לאלגוריתמים שדורשים הקטנות רבות של המפתחות (כדוגמת אלגוריתם דייקסטרה שבערימת פיבונאצ'י סיבוכיותו היא <math>\ O(|E|+|V|\log|V|)</math> לעומת <math>\ O(|E|\log|V|)</math> בערימה בינארית).

==קישורים חיצוניים==

== הערות שוליים ==

קטגוריה:עצים (גרפים)
בינומית