טבלת גיבוב – הבדלי גרסאות
תוכן שנמחק תוכן שנוסף
מ תעתיק |
מ ויקישיתוף בשורה |
||
שורה 1:
{{מבנה נתונים|תמונה = [[
הרעיון לטבלת הגיבוב הופיע כבר ב[[1953]] במזכר פנימי בחברת [[IBM]] שפורסם על ידי ה.פ. לון (H. P. Luhn) ובמקביל פותחה על ידי ג'ין אמדל (Gene amdahl), ה.מ בוהם (E. M. Boehme), נתניאל רוצ'סטר (Nathaniel Rochester) וארתור סמואל (Arthur Samuel) תוכנית שמשתמשת בגיבוב. כאשר למדען המחשב הרוסי אנדריי ארשוב (Andrey Ershov), היה את אותו רעיון כמו לאמדל.
שורה 9:
== בעיית ההתנגשות ==
פעמים רבות לא ניתן להשתמש ב"פונקציה חד-חד-ערכית", למשל, אם היינו רוצים לגשת לרשומות עובדים בעזרת מספר תעודת הזהות שלהם ושימוש [[פונקציית הזהות|בפונקציית הזהות]], אז היינו צריכים להקצות מערך של מיליארד(!) תאים כדי שיתאים לטווח של הפונקציה. הבעיה נוצרת כאשר מספר המפתחות האפשריים, גדול בהרבה מאשר מספר הרשומות שיהיו בטבלת הגיבוב
==== טבלה פתוחה וסגורה ====
שורה 24:
== פונקציית הגיבוב ==
{{הפניה לערך מורחב|פונקציית גיבוב}}
פונקציית הגיבוב מתאימה עבור כל מפתח, אינדקס במערך שיוכל להתאים עבורו. כדי שפעולות הטבלה יהיו מהירות, הפונקציה צריכה להתבצע בסיבוכיות נמוכה ביותר ביחס לערכו של המפתח עד כדי שלא יהיו תלויות בו. דרישה נוספת היא שהפונקציה תחזיר ערכים באופן קרוב עד כמה שאפשר ל[[התפלגות אחידה]].
== פעולת חיפוש ==
שורה 31:
כאשר מדובר על טבלה פתוחה, פעולת החיפוש צריכה לטפל בבעיית ההתנגשות. כלומר, המפתח הוביל אותנו אל רשומה שלא מתאימה אליו. בעיה זו נפתרת לרוב על ידי משתנה נוסף שהפונקציה מקבלת והוא מקבל ערך חדש עבור כל התנגשות נוספת בחיפוש הנוכחי. פונקציית הגיבוב מתייחסת אל המשתנה הזה כאשר היא מחזירה את הערך ותחזיר ערך חדש אחרי כל התנגשות. החיפוש נגמר כאשר מצאנו את הרשומה המתאימה או כשמגיעים לתא שלא הפנה לשום ערך. בשימוש בשיטה הזאת יכולה להתקיים בעיה כאשר מוחקים מהטבלה את אחת הרשומות שהיא גם אחת מההתנגשויות בחיפוש אחר רשומה נוספת. בפעולת החיפוש נקבל את הרושם שהגענו לתא שלא הפנה לשום רשומה ולכן נפסיק את החיפוש. הפתרון לבעיה הוא באמצעות משתנה שישמור עבור כל תא בטבלה אם הוא הפנה אל רשומה ובזמן החיפוש נבדוק באמצעות המשתנה אם התא "אוכלס" בעבר.
עבור פונקציית גיבוב טובה, סיבוכיות הזמן תהיה תלויה במספר ההתנגשויות בזמן חיפוש ערך ותהיה גבוהה יותר ככל שמספר הרשומות בטבלה, מתקרב לגודל המערך (מסומן "B<<n" כאשר B - גודל המערך, n - מספר הרשומות בפועל במערך).
בטבלה סגורה בעיית ההתנגשות נפתרת על ידי מבנה נתונים נוסף שאליו התא בטבלה מפנה. החיפוש נעשה על ידי שימוש בפונקציית שמחזירה אינדקס במערך ולאחר מכן בפונקציית החיפוש של מבנה הנתונים שאליו מפנה האינדקס.
עבור פונקציית גיבוב טובה, כאשר כמות הרשומות באותו סדר גודל של מספר התאים במערך (מסומן "B~n"), סיבוכיות החיפוש תהיה במקרה הממוצע <math>\ O(1)</math> כיוון שבכל מבנה נתונים יהיה בממוצע מספר בודד של רשומות. במקרה הגרוע, הסיבוכיות תהיה כמו הסיבוכיות במקרה הגרוע של מבנה הנתונים
== פעולת הכנסה ==
הכנסת רשומה לטבלה מתבצעת בעזרת מציאת מקום מתאים לרשומה באופן דומה לחיפוש רגיל בטבלה והכנסת הרשומה במקום שנמצא.
עבור הכנסה בטבלה פתוחה, גם כאשר מוצאים תא שהיה בעבר מאוכלס, מכניסים לתוכו את הרשומה.
בטבלה סגורה ההכנסה מתבצעת באמצעות מציאת המקום המתאים בטבלה על ידי פונקציית הגיבוב ואז שימוש בפונקציית ההכנסה של מבנה הנתונים הנוסף אתו עובדים. סיבוכיות ההכנסה תהיה כמו בחיפוש.
שורה 52:
== שיטות גיבוב ==
עבור טבלה סגורה, ניתן להשתמש במבנה הנתונים [[רשימה מקושרת]]
בטבלה הפתוחה קיימות מספר שיטות לפתירת בעיית ההתנגשות:
* '''[[בדיקה לינארית]]''' {{אנ|Linear probing}} '''-''' עבור כל התנגשות נבדוק סדרתית האם האינדקס הבא במערך פנוי. שיטה זו קלה לחישוב ולהבנה ושומרת על מקומיות בזיכרון דבר [[מדרג זיכרון|שחוסך גישה]] ל[[דיסק קשיח|דיסק הקשיח]] אך יכולה לצור בעיה של הצטברות רשומות בסדרת אינדקסים ובעקבות כך יהיה מספר גדול של התנגשויות עבור הרשומות באותם באינדקסים. ההצטברות תתהווה
* '''[[בדיקה ריבועית]]''' {{אנ|Quadratic probing}} '''-''' עבור כל התנגשות נבדק מקום מתאים אחר תוך שימוש בהעלאה בריבוע של מספר ההתנגשויות שהיו עד כה עבור אותו מפתח. הפונקציה עבור הבדיקה הריבועית היא:<math>h(k,i) = ( h(k) + c_1 i + c_2 i^2 ) \mod m</math> כאשר: <math>h</math> - פונקציית הגיבוב, <math>k</math> - המפתח המבוקש, <math>i</math> - מספר ההתנגשויות, <math>m</math> - מספר התאים בטבלה ו<math>c_1,c_2</math> - מספרים קבועים. בשיטה זו אמנם תיתכן הצטברות שתבוא לידי ביטוי בסדרות של תאים מאוכלסים שמתחילות מ<math>h(k)</math> וממשיכות בתאים שבאופן רצוף האינדקס עבורם הוא <math>h(k,i)</math> והם מאוכלסים. ההצטברות מתהווה
* '''[[גיבוב כפול]]''' {{אנ|Double hashing}} '''-''' בגיבוב כפול משתמשים בפונקציית גיבוב נוספת כדי לטפל במקרה של התנגשות. הנוסחה עבור גיבוב כפול היא: <math>h(k,i) = ( h_1(k) + i \cdot h_2(k) ) \mod m</math>
==שימושים לטבלאות גיבוב==
שורה 69:
* [[פונקציית גיבוב]]
* [[גיבוב קוקייה]]
==קישורים חיצוניים==
{{ויקישיתוף בשורה}}
{{מבני נתונים}}
|