Skip Lists םיגוליד תומישר

Shared by: ffv43448
-
Stats
views:
27
posted:
4/7/2010
language:
English
pages:
54
Document Sample
scope of work template
							 Skip lists                                                Lecture6 of Geiger & Itai’s slide brochure
                                                           www.cs.technion.ac.il/~dang/courseDS


                            Skip Lists ‫רשימות דילוגים‬
      Skip lists: A probabilistic Alternative to Balanced Trees,
      William Pugh, Communications of the ACM, 33(6):668-676,
      1990.

                       :‫ וכן באתר‬skip list animation ‫המאמר נמצא גם באתר הקורס תחת‬
      www.cs.umd.edu/users/pugh (selected publications)




Geiger & Itai, 2001
                         ‫רשימות דילוגים ‪Skip Lists‬‬
 ‫‪Skip lists‬‬                                                                             ‫2‬




                     ‫ְ ַ ְ ִׁ‬
        ‫עצים מאוזנים, 3-2 ו- ‪ AVL‬שנלמדו בשני השעורים הקודמים, מממשים את פעולות‬
                   ‫המילון (חיפוש, הכנסה, הוצאה) בזמן )‪ O(log n‬במקרה הגרוע ביותר.‬
                                                        ‫מימוש הפעולות אינו טריוויאלי,‬
       ‫במיוחד כאשר יש צורך לתמוך גם בפעולות הדורשות לשמור בכל צומת אינפורמציה‬
                                                 ‫ייחודית (כמו ‪ )rank‬ולעדכן אותה.‬


               ‫נלמד כעת מבנה נתונים בעל מימוש פשוט מאוד, שלא דורש איזונים של מבנה‬
                                                       ‫הנתונים לאחר הכנסה/הוצאה.‬
                                                                             ‫בְ ר‬
                             ‫ִׁתמּו ָה: בצוע פעולות המילון יעשה בזמן )‪ O(log n‬בממוצע.‬
                ‫ַ‬
         ‫למרות זאת, ההסתברות שזמן בצוע פעולה יחרוג בצורה משמעותית (נֹאמר פי 3)‬
                             ‫מהזמן הממוצע היא זניחה (פחות מ- 1 ל 000,000,001(.‬

‫‪cs,Technion‬‬
                                  ‫מהו "ממוצע" ?‬
 ‫‪Skip lists‬‬                                                                            ‫3‬




       ‫ראינו כבר (בשיעור 3) שעצי חיפוש ללא פעולות איזון יכולים לשמש למימוש פעולות‬
                                                   ‫המילון בזמן )‪ O(log n‬ב"ממוצע".‬
    ‫מהו הממוצע הזה ? בניתוח שעשינו הנחנו שהוכנסו ‪ n‬איברים כך שההסתברות לכל‬
     ‫אחת מ- !‪ n‬הפרמוטציות להכנסתם אחידה. הממוצע של גובה !‪ n‬העצים שנוצרו הוא‬
                                  ‫)‪ .O(log n‬אבל – ההנחה שעשינו הינה על הקלט!‬
         ‫הבעייתיות בניתוח זה: ההסתברות להופעת פרמוטציה בקלט אינה ידועה ואין שום‬
       ‫סיבה להניח יוניפורמיות. אנו מעוניינים במבני נתונים + הבטחות ביצועים ללא תלות‬
                           ‫ֲ ִׁ ינ‬                                       ‫ְְָֺ‬
       ‫בהנחות מפקפקֹות על הקלט. בפרט היינו מעוניינים להיות חס ִׁים ל-"יריב" המעוניין‬
                                                          ‫להאיט את ריצת האלגוריתמים.‬
                 ‫ברשימות דילוגים, שעליהן נלמד היום, נקבל ביצוע בזמן )‪ O(log n‬בממוצע.‬
               ‫אולם: המבנה וזמן ביצוע הפעולות תלויים בהגרלות שעושה המחשב ולא בסדר‬
                ‫הכנסת הנתונים. הממוצע מחושב לפי ההגרלות ולא לפי הנחות על הסתברות‬
                                     ‫הקלטים. אלגוריתם כזה נקרא אלגוריתם רנדומלי.‬
‫‪cs,Technion‬‬
                                       ‫הרעיון המרכזי‬
 ‫‪Skip lists‬‬                                                                                 ‫4‬



                                                           ‫חיפוש איבר בסוף רשימה הוא יקר.‬

               ‫5‬      ‫11‬    ‫31‬    ‫51‬     ‫71‬     ‫02‬    ‫32‬    ‫13‬     ‫23‬   ‫53‬   ‫54‬   ‫74‬

                   ‫כדי לזרז את החיפוש (פי שניים) נוסיף מד ִׁיך– תת רשימה של כל איבר שני:‬
                                             ‫ַ ְר ְ‬
               ‫5‬           ‫31‬           ‫71‬            ‫32‬           ‫23‬        ‫54‬

               ‫5‬      ‫11‬   ‫31‬    ‫51‬     ‫71‬     ‫02‬     ‫32‬   ‫13‬      ‫23‬   ‫53‬   ‫54‬   ‫74‬


                                                             ‫מהו זמן החיפוש המינימלי?‬

                                                ‫‪n‬‬

                     ‫‪n‬‬           ‫2‬     ‫‪n  O‬‬   ‫‪ n‬‬    ‫זמן חיפוש‬

‫‪cs,Technion‬‬
 ‫‪Skip lists‬‬                                                                     ‫5‬




                                   ‫כדי לזרז את החיפוש במדריך נוסיף רמה נוספת:‬
        ‫5‬                     ‫71‬                    ‫23‬

        ‫5‬           ‫31‬        ‫71‬         ‫32‬         ‫23‬         ‫54‬

        ‫5‬      ‫11‬   ‫31‬   ‫51‬   ‫71‬   ‫02‬    ‫32‬   ‫13‬    ‫23‬   ‫53‬    ‫54‬    ‫74‬




                                     ‫וכך הלאה עד לרמה ‪ log n‬ובה איבר בודד.‬




‫‪cs,Technion‬‬
                                  ‫אלגוריתם החיפוש‬
 ‫‪Skip lists‬‬                                                                          ‫6‬




              ‫נניח שמחפשים מפתח ‪ .x‬נתחיל משורש המבנה. בכל רמה נצעד ימינה כל עוד‬
              ‫המפתחות שנסרקים קטנים או שווים ל-‪ .x‬עם מיצוי הרמה נרד רמה אחת, וכו'.‬

 ‫שורש‬

               ‫5‬
               ‫5‬                                            ‫23‬


               ‫5‬                     ‫71‬                     ‫23‬

               ‫5‬          ‫31‬         ‫71‬          ‫32‬         ‫23‬         ‫54‬

               ‫5‬     ‫11‬   ‫31‬    ‫51‬   ‫71‬    ‫02‬    ‫32‬   ‫13‬    ‫23‬   ‫53‬    ‫54‬    ‫74‬


‫‪cs,Technion‬‬
                                ‫אורך מסלול החיפוש‬
 ‫‪Skip lists‬‬                                                                            ‫7‬




                               ‫נסתכל על מסלול החיפוש מצומת הסיום ועד צומת ההתחלה.‬
                              ‫במעבר מרמה לרמה אנו עוברים על פני 2 מצביעים לכל היותר.‬
                                                      ‫לפיכך אורך המסלול הוא ‪.2log n‬‬
               ‫5‬
               ‫5‬                                            ‫23‬   ‫מספר הצמתים הכולל‬
                                                                      ‫אינו עולה על ‪.2n‬‬
               ‫5‬                      ‫71‬                    ‫23‬

               ‫5‬         ‫31‬          ‫71‬          ‫32‬         ‫23‬          ‫54‬

               ‫5‬   ‫11‬    ‫31‬     ‫51‬    ‫71‬   ‫02‬    ‫32‬   ‫13‬    ‫23‬   ‫53‬     ‫54‬    ‫74‬

      ‫הבעיה שנותר לפתור היא כיצד לשמור על המבנה שיצרנו בעת הכנסה והוצאה מבלי‬
                                          ‫שיהיה צורך לארגן את כל הרמות מחדש.‬
               ‫נשים לב שאלגוריתם החיפוש נכון גם אם מספר הצמתים של רמה ‪ i‬בין כל שני‬
‫‪cs,Technion‬‬                                            ‫צמתים של רמה 1-‪ i‬אינו קבוע.‬
                      ‫הכנסה באמצעות הטלת מטבע‬
 ‫‪Skip lists‬‬                                                                        ‫8‬



                                                            ‫צעדים להכנסת מפתח ‪.k‬‬
                                                  ‫1. חפש את ‪ .k‬אם ‪ k‬נמצא סיים.‬
               ‫2. הוסף צומת חדש עם מפתח ‪ k‬ברמה התחתונה ביותר (במקום המתאים!)‬
                                                 ‫3. לפי סדר הרמות מלמטה למעלה:‬
                  ‫הגרל מטבע ) (‪ .toss‬אם יוצא 0: הוסף צומת חדש מעל הרמה‬
                       ‫הנוכחית וקבע את המפתח בו להיות ‪ .k‬אם יוצא 1, עצור.‬
                                  ‫4. אם ברמה העליונה הוגרל 0, הוסף רמה חדשה.‬
   ‫הגרלה‬
          ‫1‬       ‫5‬                   ‫71‬                      ‫23‬        ‫הכנס 13:‬

         ‫0‬        ‫5‬         ‫31‬                    ‫32‬   ‫13‬     ‫23‬          ‫54‬
                                      ‫71‬

                  ‫5‬    ‫11‬   ‫31‬   ‫51‬   ‫71‬    ‫02‬    ‫32‬   ‫13‬     ‫23‬   ‫53‬     ‫54‬   ‫74‬
‫‪cs,Technion‬‬
                           ‫הוצאה מרשימת דילוגים‬
‫‪Skip lists‬‬                                                                             ‫9‬



                                                      ‫מצא את האיבר בעל המפתח ‪.k‬‬   ‫1.‬
                                          ‫הוצא איבר זה מכל הרמות בהם הוא מופיע.‬   ‫2.‬

                                ‫71‬               ‫13‬                        ‫הוצא 71:‬


                 ‫11‬             ‫71‬   ‫02‬          ‫13‬                  ‫54‬


             ‫5‬   ‫11‬   ‫31‬   ‫51‬   ‫71‬   ‫02‬   ‫32‬     ‫13‬      ‫23‬    ‫53‬    ‫54‬    ‫74‬



                                                ‫13‬


                 ‫11‬                  ‫02‬         ‫13‬                   ‫54‬


             ‫5‬   ‫11‬   ‫31‬   ‫51‬        ‫02‬   ‫32‬    ‫13‬       ‫23‬    ‫53‬    ‫54‬    ‫74‬
                               ‫תוכניות לרשימת דילוגים‬
 Skip lists                                                                     10




  typedef struct node {                         .‫הגדרת צומת ופרוצדורת עזר ליצירתו‬
               Key value ;
               struct node *next, *down ;                              next
                                                         value
               } NODE ;                                                down
  NODE *top ;

                  NODE *new_node (KEY k, NODE *n, NODE *d)
                  {       NODE *p ;
                          p = (NODE *) malloc( sizeof ( NODE )) ;
                          p  value = k ;
                          p  next = n ;
                          p  down = d ;
cs,Technion
                          return p ; }
                               ‫הערות לגבי התוכניות‬
 ‫‪Skip lists‬‬                                                                        ‫11‬




               ‫נוח להוסיף בכל רמה צומת אחד בהתחלת הרשימה שמפתחו ‪ -‬וצומת אחד‬
                                                ‫בסוף שמפתחו ‪.)sentinel( +‬‬
                 ‫תוכנית ההכנסה רקורסיבית אך ניתן לכתוב אותה גם ללא רקורסיה בקלות‬
                                                                           ‫רבה.‬
              ‫באתר הקורס תחת ‪ skip list animation‬קיים קוד לא רקורסיבי בשפת ++‪C‬‬
                              ‫ובשפת ‪ .Java‬יש הבדלים מסוימים בין התוכניות השונות.‬
                  ‫הפרוצדורה )‪ add_after(k,p‬מוסיפה צומת חדש בעל מפתח ‪ k‬אחרי ‪,p‬‬
                                                           ‫ומחזירה מצביע אליו.‬
                                 ‫הפרוצדורה ) (‪ toss‬מחזירה 0 או 1 בהסתברות שווה.‬




‫‪cs,Technion‬‬
                             ‫תוכנית חיפוש ברשימת דילוגים‬
 Skip lists                                                                             12




   NODE *search (KEY k, NODE *p)
   {              /* returns a pointer p to last node  k */
                  while(1) { for ( ; p  next  value <= k ; p = p  next) ;
                          if ( p  down = = NULL) break; /* final level */
                          p = p  down ; }
                  return p ; }

                                                                     .‫מצא 71: לא נמצא‬
 -                                                      31


 -                  11                      20          31              45         


 -           5      11     13   15          20    23    31    32   35   45    47
cs,Technion
                       ‫תוכנית להכנסה ברשימת דילוגים‬
Skip lists                                                                                             13


NODE *insert1 (KEY k, NODE *p)
{            /* returns a pointer to the added node */
     NODE * deeper, *new_node;
     for ( ; p  next!=NULL && p  nextvalue <= k ; p = pnext) ;
     if ( p  down = = NULL) return add_after(k,p) ;        /* final level */
     deeper = insert1(k, pdown);
     if (( deeper == NULL || toss( ) ) then { return NULL};
     else { new_node = add_after(k,p) ;                                   add_after(k,p) ‫הפרוצדורה‬
             new_node  down = deeper ;}                        ,p ‫ אחרי‬k ‫מוסיפה צומת חדש בעל מפתח‬
    return new_node; }                                                           .‫ומחזירה מצביע אליו‬

-                                    17                     31                           :17 ‫הכנס‬


-               11                   17      20             31                    45             


-           5   11     13     15     17      20     23      31     32     35      45      47
                                 ‫הכנסה ברמה העליונה‬
Skip lists                                                                               14



NODE *insert (KEY k, NODE *old_list)
{        /* returns a pointer to the added node */
     NODE * deeper ;
     deeper = insert1(k, old_list);
     if (( deeper == NULL || toss( ) ) return old_list ;
     return new_node(-INFINITY, inf-addrs, old_list); }


-

                                                                                :17 ‫הכנס‬
-                                      17                  31


-               11                    17      20           31             45        


-           5   11     13      15     17      20      23   31   32   35   45   47
                   ‫בכמה רמות בממוצע מופיע כל מפתח ?‬
 ‫‪Skip lists‬‬                                                                       ‫51‬




                  ‫בכל רמה האלגוריתם מטיל מטבע כדי לקבוע אם יוצר העתק נוסף מעליה.‬
          ‫מספר הרמות הממוצע למפתח שווה למספר הפעמים הממוצע שיש להטיל מטבע‬
                                                             ‫הֹו ֵן עד שיצא 1.‬
                                                                         ‫ג‬
         ‫מספר הפעמים הממוצע שיש להטיל מטבע הוגן עד שיצא 1 הוא 2. (הוכחה בשקף‬
                   ‫הבא. אינטואיציה:בממוצע מטבע נופל פעם על צד 0 ופעם על צד 1).‬

 ‫‪-‬‬                                                ‫13‬


 ‫‪-‬‬               ‫11‬              ‫71‬   ‫02‬          ‫13‬              ‫54‬         ‫‪‬‬


 ‫‪-‬‬           ‫5‬   ‫11‬   ‫31‬    ‫51‬   ‫71‬   ‫02‬    ‫32‬    ‫13‬   ‫23‬   ‫53‬    ‫54‬   ‫74‬

                   ‫מסקנה (לא פורמלית): מספר הצמתים הממוצע הוא ‪ 2n‬כאשר ‪ n‬הוא‬
                          ‫מספר המפתחות במבנה (כל מפתח מופיע בממוצע פעמיים).‬
‫‪cs,Technion‬‬
                     ‫מהו אורך מסלול חיפוש ממוצע ?‬
‫‪Skip lists‬‬                                                                      ‫61‬



             ‫משפט: האורך הממוצע ‪ L‬של מסלול חיפוש ברשימת דילוגים עם ‪ n‬מפתחות‬
                                                     ‫מקיים 2 + )‪.L  2log2(n‬‬
                             ‫ֲ ַנ‬
    ‫הוכחה: נסתכל על מסלול חיפוש מנקודת הסיום אחֹורִׁית לנקודת ההתחלה. המסלול‬
    ‫מורכב מתנועה מעלה (כשאפשר) ותנועה שמאלה (כשחייבים). כאשר מגיעים לקצה‬
                               ‫השמאלי ביותר, התנועה ממשיכה כלפי מעלה בלבד.‬

                             ‫נסמן ב- )‪ c(k‬את אורך המסלול הממוצע המטפס ‪ k‬רמות.‬
                                      ‫ְֵַַ‬
                             ‫0 = )0(‪c‬‬                                   ‫מתקיים:‬
                             ‫))1-‪c(k)  ½ (1+ c(k)) + ½ (1 + c(k‬‬
               ‫הסבר: צעד שמאלה בהסתברות ½ (אם אפשר) וצעד מעלה בהסתברות ½.‬

                      ‫)1-‪c(k)  2 + c(k‬‬                            ‫לפיכך:‬
                             ‫‪c(k)  4 + c(k-2)  …  2k‬‬                     ‫ולכן:‬
             ‫כלומר אורך מסלול ממוצע מרמה 1 לרמה )‪ log2(n‬מקיים: )1-)‪L  2(log2(n‬‬
                           ‫אורך מסלול חיפוש (המשך)‬
 ‫‪Skip lists‬‬                                                                      ‫71‬



              ‫המשך ההוכחה: נותר לקחת בחשבון את המקרים שבהם מספר הרמות גדול מ-‬
                                                                       ‫)‪.log2(n‬‬
         ‫מעל הרמה ה- )‪ log2(n‬מספר הצעדים הממוצע שמאלה חסום ע"י מספר האיברים‬
       ‫הממוצע ברשימת הדילוגים שהוכנסו מעל רמה זו. מספרם הממוצע חסום ע"י 2 שכן‬
                                        ‫בכל רמה מספר האיברים הממוצע קטן פי 2.‬
                                                     ‫מהו מספר הצעדים כלפי מעלה?‬

     ‫ניתן להראות שמספר הרמות המקסימלי הממוצע עבור רשימת דילוגים עם ‪ n‬איברים‬
                                                          ‫קטן מ- 2 + )‪log2(n‬‬
                    ‫כלומר מספר הצעדים הממוצע כלפי מעלה מעל הרמה )‪ log2(n‬הוא 2.‬

                   ‫לפיכך סך אורכו הממוצע של מסלול חיפוש מקיים: 4+)1-)‪L  2(log2(n‬‬
                                                                   ‫כמצוין במשפט.‬
‫‪cs,Technion‬‬
                           ‫זמן בצוע הפעולות‬
‫‪Skip lists‬‬                                                                   ‫81‬



             ‫מסקנה מהמשפט: חיפוש, הכנסה, והוצאה מרשימת דילוגים נעשים בזמן‬
                 ‫ממוצע )‪ O(log n‬כיון שבכל צעד על מסלול החיפוש מתבצעים )1(‪O‬‬
                                                                    ‫צעדים.‬
                                                               ‫הטלת מטבע‬
‫‪Skip lists‬‬                                                                                                                          ‫91‬




               ‫נניח שלמטבע הסתברות ‪ p‬לצאת "זנב" (נסמן צד זה באפס) והסתברות ‪1-p‬‬
                                                   ‫לצאת "ראש" (נסמן צד זה באחד).‬
                                ‫כמה פעמים בממוצע ‪ L‬יש להטיל את המטבע עד שנקבל "ראש" ?‬
                               ‫נסמן ב- ‪ Qi‬את ההסתברות שנקבל "ראש" לראשונה בהטלה ה- ‪.i‬‬


                                                  ‫)‪Qi = pi-1 (1-p‬‬                    ‫0=0‪Q‬‬                                 ‫מתקיים:‬

                   ‫‪‬‬                ‫‪‬‬                                         ‫‪‬‬
                                                                                                 ‫‪1 p‬‬               ‫1‬
                   ‫‪‬‬                ‫‪‬‬
                                                  ‫1‪i ‬‬
             ‫‪L ‬‬          ‫‪i Qi ‬‬          ‫‪i p‬‬          ‫‪(1  p )  (1  p )  i  p i  1 ‬‬                   ‫‪‬‬
                                                                                                ‫‪1  p ‬‬
                                                                                                           ‫2‬
                   ‫1‪i ‬‬             ‫1‪i ‬‬                                      ‫1‪i ‬‬                                 ‫‪1 p‬‬

                                                                                            ‫1‬
                               ‫הטלות עד שמקבלים "ראש".‬                               ‫‪L ‬‬                   ‫כלומר בממוצע נדרשות‬
                                                                                           ‫‪1 p‬‬


                                      ‫ועבור מטבע הוגן, כאשר ½ = ‪, p‬נדרשות 2=‪ L‬הטלות בממוצע.‬
 Skip lists                                                                                         20



                                                                                  :‫הוכחה פשוטה‬
                                                       0
                                                   p
                                              0
                                        p
                                0
                         p                  (1  p )
                                                           1
                             (1  p )
                                               1
                     (1  p )                                                        0
                                    1                                         p              L 1
                                                                      L
                                                                          (1  p )
                                                                                         1

               L  p ( L  1)  (1  p )1

                                                                1
               L (1  p )  1                      L 
                                                               1 p
cs,Technion
                                 ‫ֻ ֶּ‬
                                ‫שימוש במטבע מטה‬
‫‪Skip lists‬‬                                                                        ‫12‬




             ‫כאשר משתמשים במטבע עם הסתברות לקבלת “זנב" ‪ ,p‬אזי מספר ההעתקים‬
                  ‫הממוצע לכל מפתח הוא )‪ 1/(1-p‬ומספר הרמות הממוצע הוא )‪.log1/p(n‬‬

               ‫הכללת המשפט: האורך הממוצע ‪ L‬של מסלול חיפוש ברשימת דילוגים עם ‪n‬‬
                                 ‫מפתחות כאשר למטבע הסתברות ‪ p‬לצאת “זנב" מקיים‬
                       ‫‪( .L  1/plog1/p(n) + 1/p‬כלומר 2 מוחלף ב- ‪.)1/p‬‬


‫לפיכך, לפרמטר ‪ p‬אין השפעה גדולה (בגבולות סב ִׁים) על האורך הממוצע של מסלול‬
                            ‫ְ ִׁיר‬
                                                                    ‫חיפוש.‬
‫‪Skip lists‬‬

                       ‫אלגוריתם הכנסה לא רקורסיבי ברשימת דילוגים‬
   ‫)05(‪Insert‬‬

             ‫‪‬‬                                    ‫09‬


             ‫‪‬‬              ‫44‬                    ‫09‬
                                                           ‫‪+‬‬

             ‫‪‬‬   ‫31‬   ‫03‬    ‫44‬   ‫05‬   ‫75‬   ‫66‬     ‫09‬


                       ‫)75(‪Delete‬‬                  ‫1‬
Skip lists




                       Insert(56)
                                              90


                          44                  90
                                                     +

                13   30   44   50   56   66   90


                                                0
Skip lists




                                              90


                          44        56        90
                                                     +

                13   30   44   50   56   66   90


                                                1
                                                0
Skip lists



                  Deterministic Insert and Delete

                                                   90


                               44        56        90
                                                          +

                 13       30   44   50   56   66   90

                        2             1         1
                             Insert(77)
Skip lists




                                                         90
                                  T

                        44          56                   90
                                              q                 +

           13    30     44    50    56     66       77   90

                   q = T->down->next->next        2
              T->next->down is q->next or q


Insert(80)
Skip lists




                                                         90
                                 T

                       44          56                    90
                                                                +
                                           q

           13   30     44    50    56   66     77   80   90

                       q = T->down->next->next
                  T->next->down is q->next or q
Skip lists




  T

                                                         90
                                 q

                       44          56          77        90
                                                                +

           13   30     44    50    56   66     77   80   90

                       q = T->down->next->next
                  T->next->down is q->next or q
Skip lists


                            Delete(77)


                               56                  90


                     44        56        77        90
                                                          +

           13   30   44   50   56   66   77   80   90
Skip lists


                            Delete(77)


                               56                  90


                     44        56        77        90
                                                          +

           13   30   44   50   56   66   77   80   90
Skip lists




                               56                  90


                     44        56        77        90
                                                          +

           13   30   44   50   56   66        80   90
Skip lists


                             Delete(56)


                               56             90


                     44        56             90
                                                     +

           13   30   44   50   56   66   80   90
Skip lists


                             Delete(56)


                               56             90


                     44        56             90
                                                     +

           13   30   44   50   56   66   80   90
Skip lists




                               56             90


                     44        56             90
                                                     +

           13   30   44   50        66   80   90
Skip lists




                               66             90


                     44        66             90
                                                     -

           13   30   44   50        66   80   90
 ‫‪Skip lists‬‬                                                                         ‫63‬

                             ‫רשימת דילוגים דטרמיניסטית‬
                              ‫‪Deterministic Skip List‬‬
                                        ‫נראה כעת כיצד לממש ‪ skip list‬דטרמיניסטי.‬
                ‫מבנה נתונים זה מאפשר פעולות חיפוש/הכנסה/הוצאה כמו בעצים מאוזנים‬
                                                            ‫(ובסיבוכיות זמן זהה).‬
                                           ‫נתאר כעת בפרוטרוט את פעולת ההכנסה.‬
                                           ‫אח"כ נציג את המבנה בהקשר של עצי 2-3.‬

  ‫‪T‬‬

               ‫‪-‬‬                                   ‫13‬
                                                                             ‫‪‬‬
               ‫‪-‬‬       ‫11‬                ‫02‬        ‫13‬             ‫54‬

               ‫‪-‬‬   ‫5‬   ‫11‬   ‫31‬   ‫51‬      ‫02‬   ‫32‬   ‫13‬   ‫23‬   ‫53‬   ‫54‬   ‫74‬
‫‪cs,Technion‬‬
                                    ‫הרעיון העיקרי‬
 ‫‪Skip lists‬‬                                                                         ‫73‬




                    ‫יש לשמור שמספר הצמתים של רמה ‪ i‬בין כל שני צמתים של רמה 1-‪i‬‬
                   ‫יהיה 1 או 2. אם מספר הצמתים הוא 3, מוסיפים צומת ברמה ה- )1-‪.(i‬‬

                                                                       ‫דוגמא: הכנס 71‬
        ‫‪-‬‬                     ‫51‬                  ‫13‬
                                                                                ‫‪‬‬
        ‫‪-‬‬           ‫11‬        ‫51‬        ‫02‬        ‫13‬             ‫54‬

        ‫‪-‬‬     ‫5‬     ‫11‬   ‫31‬   ‫51‬   ‫71‬   ‫02‬   ‫32‬   ‫13‬   ‫23‬   ‫53‬   ‫54‬    ‫74‬



                   ‫הערה: בניגוד לרשימת דילוגים (רנדומלית) המפתח שמוכנס אינו בהכרח‬
               ‫המפתח שמשוכפל ברמה מעל. בדוגמא הוכנס 71 אך שוכפל המפתח 51.‬

‫‪cs,Technion‬‬
 Skip lists                                                                                                 38
                         ‫תוכנית להכנסה ברשימת דילוגים דטרמיניסטית‬

  int insert1(int x, NODE *T)
  { /* returns 1 iff new node allocated on this level */
  NODE * q ;
  for ( ; T  next  value <= x ; T = T  next) ;                                .‫חיפוש ברמה נוכחית‬
  if (T  down = = NULL){ /* a leaf */
              T  next = get_node(x, T  next, NULL);                          .‫הוספה ברמה תחתונה‬
              return 1;
  }
  if (!insert1(x, T  down) ) return 0;                                             .‫קריאה רקורסיבית‬
  /* check if as result of insertion, there are three nodes
   between T  down and T  next  down */
  q = T  down  next  next ;
  if ( q  next  value < T  next  value ) {                               .‫חזרה מקריאה רקורסיבית‬
        T  next = get_node(q  value, T  next, q);
        return 1 ;
  }
  return 0 ;                       T                                                           17 ‫דוגמא: הכנס‬
  }
                        -                                              31
                                                                                                        
                       -           11                        20        31                45

                       -      5    11     13    15           20   23   31     32    35   45    47
cs,Technion
 Skip lists                                                                                                 39
                         ‫תוכנית להכנסה ברשימת דילוגים דטרמיניסטית‬

  int insert1(int x, NODE *T)
  { /* returns 1 iff new node allocated on this level */
  NODE * q ;
  for ( ; T  next  value <= x ; T = T  next) ;                                .‫חיפוש ברמה נוכחית‬
  if (T  down = = NULL){ /* a leaf */
              T  next = get_node(x, T  next, NULL);                          .‫הוספה ברמה תחתונה‬
              return 1;
  }
  if (!insert1(x, T  down) ) return 0;                                             .‫קריאה רקורסיבית‬
  /* check if as result of insertion, there are three nodes
   between T  down and T  next  down */
  q = T  down  next  next ;
  if ( q  next  value < T  next  value ) {                               .‫חזרה מקריאה רקורסיבית‬
        T  next = get_node(q  value, T  next, q);
        return 1 ;
  }
  return 0 ;                                                                                   17 ‫דוגמא: הכנס‬
  }
                        -                                              31
                                   T
                                                                                                        
                       -           11                        20        31                45

                       -      5    11     13    15           20   23   31     32    35   45    47
cs,Technion
 Skip lists                                                                                                 40
                         ‫תוכנית להכנסה ברשימת דילוגים דטרמיניסטית‬

  int insert1(int x, NODE *T)
  { /* returns 1 iff new node allocated on this level */
  NODE * q ;
  for ( ; T  next  value <= x ; T = T  next) ;                                .‫חיפוש ברמה נוכחית‬
  if (T  down = = NULL){ /* a leaf */
              T  next = get_node(x, T  next, NULL);                          .‫הוספה ברמה תחתונה‬
              return 1;
  }
  if (!insert1(x, T  down) ) return 0;                                             .‫קריאה רקורסיבית‬
  /* check if as result of insertion, there are three nodes
   between T  down and T  next  down */
  q = T  down  next  next ;
  if ( q  next  value < T  next  value ) {                               .‫חזרה מקריאה רקורסיבית‬
        T  next = get_node(q  value, T  next, q);
        return 1 ;
  }
  return 0 ;                                                                                   17 ‫דוגמא: הכנס‬
  }
                        -                                              31
                                                 T
                                                                                                        
                       -           11                        20        31                45

                       -      5    11     13    15           20   23   31     32    35   45    47
cs,Technion
 Skip lists                                                                                                 41
                         ‫תוכנית להכנסה ברשימת דילוגים דטרמיניסטית‬

  int insert1(int x, NODE *T)
  { /* returns 1 iff new node allocated on this level */
  NODE * q ;
  for ( ; T  next  value <= x ; T = T  next) ;                                .‫חיפוש ברמה נוכחית‬
  if (T  down = = NULL){ /* a leaf */
              T  next = get_node(x, T  next, NULL);                          .‫הוספה ברמה תחתונה‬
              return 1;
  }
  if (!insert1(x, T  down) ) return 0;                                             .‫קריאה רקורסיבית‬
  /* check if as result of insertion, there are three nodes
   between T  down and T  next  down */
  q = T  down  next  next ;
  if ( q  next  value < T  next  value ) {                               .‫חזרה מקריאה רקורסיבית‬
        T  next = get_node(q  value, T  next, q);
        return 1 ;
  }
  return 0 ;                                                                                   17 ‫דוגמא: הכנס‬
  }
                        -                                              31
                                                                                                        
                       -           11                        20        31                45
                                                T
                       -      5    11     13       15        20   23   31     32    35   45    47
cs,Technion
 Skip lists                                                                                                 42
                         ‫תוכנית להכנסה ברשימת דילוגים דטרמיניסטית‬

  int insert1(int x, NODE *T)
  { /* returns 1 iff new node allocated on this level */
  NODE * q ;
  for ( ; T  next  value <= x ; T = T  next) ;                                .‫חיפוש ברמה נוכחית‬
  if (T  down = = NULL){ /* a leaf */
              T  next = get_node(x, T  next, NULL);                          .‫הוספה ברמה תחתונה‬
              return 1;
  }
  if (!insert1(x, T  down) ) return 0;                                             .‫קריאה רקורסיבית‬
  /* check if as result of insertion, there are three nodes
   between T  down and T  next  down */
  q = T  down  next  next ;
  if ( q  next  value < T  next  value ) {                               .‫חזרה מקריאה רקורסיבית‬
        T  next = get_node(q  value, T  next, q);
        return 1 ;
  }
  return 0 ;                                                                                   17 ‫דוגמא: הכנס‬
  }
                        -                                              31
                                                                                                        
                       -           11                        20        31                45
                                                      T
                       -      5    11     13    15           20   23   31     32    35   45    47
cs,Technion
 Skip lists                                                                                                     43
                        ‫תוכנית להכנסה ברשימת דילוגים דטרמיניסטית‬

  int insert1(int x, NODE *T)
  { /* returns 1 iff new node allocated on this level */
  NODE * q ;
  for ( ; T  next  value <= x ; T = T  next) ;                                    .‫חיפוש ברמה נוכחית‬
  if (T  down = = NULL){ /* a leaf */
              T  next = get_node(x, T  next, NULL);                              .‫הוספה ברמה תחתונה‬
              return 1;
  }
  if (!insert1(x, T  down) ) return 0;                                                 .‫קריאה רקורסיבית‬
  /* check if as result of insertion, there are three nodes
   between T  down and T  next  down */
  q = T  down  next  next ;
  if ( q  next  value < T  next  value ) {                                   .‫חזרה מקריאה רקורסיבית‬
        T  next = get_node(q  value, T  next, q);
        return 1 ;
  }
  return 0 ;                                                                                       17 ‫דוגמא: הכנס‬
  }
                        -                                                  31
                                                                                                            
                       -           11                            20        31                45
                                                              T
                       -      5    11     13    15               20   23   31     32    35   45    47
cs,Technion
 Skip lists                                                                                                     44
                         ‫תוכנית להכנסה ברשימת דילוגים דטרמיניסטית‬

  int insert1(int x, NODE *T)
  { /* returns 1 iff new node allocated on this level */
  NODE * q ;
  for ( ; T  next  value <= x ; T = T  next) ;                                    .‫חיפוש ברמה נוכחית‬
  if (T  down = = NULL){ /* a leaf */
              T  next = get_node(x, T  next, NULL);                              .‫הוספה ברמה תחתונה‬
              return 1;
  }
  if (!insert1(x, T  down) ) return 0;                                                 .‫קריאה רקורסיבית‬
  /* check if as result of insertion, there are three nodes
   between T  down and T  next  down */
  q = T  down  next  next ;
  if ( q  next  value < T  next  value ) {                                   .‫חזרה מקריאה רקורסיבית‬
        T  next = get_node(q  value, T  next, q);
        return 1 ;
  }
  return 0 ;                                                                                       17 ‫דוגמא: הכנס‬
  }
                        -                                                  31
                                                                                                            
                       -           11                            20        31                45
                                                              T
                       -      5    11     13    15     17        20   23   31     32    35   45    47
cs,Technion
 Skip lists                                                                                                   45
                         ‫תוכנית להכנסה ברשימת דילוגים דטרמיניסטית‬

  int insert1(int x, NODE *T)
  { /* returns 1 iff new node allocated on this level */
  NODE * q ;
  for ( ; T  next  value <= x ; T = T  next) ;                                  .‫חיפוש ברמה נוכחית‬
  if (T  down = = NULL){ /* a leaf */
              T  next = get_node(x, T  next, NULL);                            .‫הוספה ברמה תחתונה‬
              return 1;
  }
  if (!insert1(x, T  down) ) return 0;                                               .‫קריאה רקורסיבית‬
  /* check if as result of insertion, there are three nodes
   between T  down and T  next  down */
  q = T  down  next  next ;
  if ( q  next  value < T  next  value ) {                                 .‫חזרה מקריאה רקורסיבית‬
        T  next = get_node(q  value, T  next, q);
        return 1 ;
  }
  return 0 ;                                                                                     17 ‫דוגמא: הכנס‬
  }
                        -                                                31
                                                T                                                         
                       -           11                        q 20        31                45

                       -      5    11     13    15     17     20    23   31     32    35   45    47
cs,Technion
 Skip lists                                                                                                   46
                         ‫תוכנית להכנסה ברשימת דילוגים דטרמיניסטית‬

  int insert1(int x, NODE *T)
  { /* returns 1 iff new node allocated on this level */
  NODE * q ;
  for ( ; T  next  value <= x ; T = T  next) ;                                  .‫חיפוש ברמה נוכחית‬
  if (T  down = = NULL){ /* a leaf */
              T  next = get_node(x, T  next, NULL);                            .‫הוספה ברמה תחתונה‬
              return 1;
  }
  if (!insert1(x, T  down) ) return 0;                                               .‫קריאה רקורסיבית‬
  /* check if as result of insertion, there are three nodes
   between T  down and T  next  down */
  q = T  down  next  next ;
  if ( q  next  value < T  next  value ) {                                 .‫חזרה מקריאה רקורסיבית‬
        T  next = get_node(q  value, T  next, q);
        return 1 ;
  }
  return 0 ;                                                                                     17 ‫דוגמא: הכנס‬
  }
                        -                                                31
                                                T                                                         
                       -           11           15           q 20        31                45

                       -      5    11     13    15     17     20    23   31     32    35   45    47
cs,Technion
 Skip lists                                                                                                     47
                         ‫תוכנית להכנסה ברשימת דילוגים דטרמיניסטית‬

  int insert1(int x, NODE *T)
  { /* returns 1 iff new node allocated on this level */
  NODE * q ;
  for ( ; T  next  value <= x ; T = T  next) ;                                    .‫חיפוש ברמה נוכחית‬
  if (T  down = = NULL){ /* a leaf */
              T  next = get_node(x, T  next, NULL);                              .‫הוספה ברמה תחתונה‬
              return 1;
  }
  if (!insert1(x, T  down) ) return 0;                                                 .‫קריאה רקורסיבית‬
  /* check if as result of insertion, there are three nodes
   between T  down and T  next  down */
  q = T  down  next  next ;
  if ( q  next  value < T  next  value ) {                                   .‫חזרה מקריאה רקורסיבית‬
        T  next = get_node(q  value, T  next, q);
        return 1 ;
  }
  return 0 ;
                                  T                                                                17 ‫דוגמא: הכנס‬
  }
                       -                                                   31
                                                              q
                                                                                                            
                       -           11           15               20        31                45

                       -      5    11     13    15     17        20   23   31     32    35   45    47
cs,Technion
 Skip lists                                                                                                     48
                         ‫תוכנית להכנסה ברשימת דילוגים דטרמיניסטית‬

  int insert1(int x, NODE *T)
  { /* returns 1 iff new node allocated on this level */
  NODE * q ;
  for ( ; T  next  value <= x ; T = T  next) ;                                    .‫חיפוש ברמה נוכחית‬
  if (T  down = = NULL){ /* a leaf */
              T  next = get_node(x, T  next, NULL);                              .‫הוספה ברמה תחתונה‬
              return 1;
  }
  if (!insert1(x, T  down) ) return 0;                                                 .‫קריאה רקורסיבית‬
  /* check if as result of insertion, there are three nodes
   between T  down and T  next  down */
  q = T  down  next  next ;
  if ( q  next  value < T  next  value ) {                                   .‫חזרה מקריאה רקורסיבית‬
        T  next = get_node(q  value, T  next, q);
        return 1 ;
  }
  return 0 ;                       T                                                               17 ‫דוגמא: הכנס‬
  }
                        -                         15                       31
                                                              q
                                                                                                            
                       -           11           15               20        31                45

                       -      5    11     13    15     17        20   23   31     32    35   45    47
cs,Technion
 Skip lists                                                                                                49
                         ‫תוכנית להכנסה ברשימת דילוגים דטרמיניסטית‬

  int insert1(int x, NODE *T)
  { /* returns 1 iff new node allocated on this level */
  NODE * q ;
  for ( ; T  next  value <= x ; T = T  next) ;                                .‫חיפוש ברמה נוכחית‬
  if (T  down = = NULL){ /* a leaf */
              T  next = get_node(x, T  next, NULL);                          .‫הוספה ברמה תחתונה‬
              return 1;
  }
  if (!insert1(x, T  down) ) return 0;                                             .‫קריאה רקורסיבית‬
  /* check if as result of insertion, there are three nodes
   between T  down and T  next  down */
  q = T  down  next  next ;
  if ( q  next  value < T  next  value ) {                               .‫חזרה מקריאה רקורסיבית‬
        T  next = get_node(q  value, T  next, q);
        return 1 ;
  }
  return 0 ;                       T                                         .‫דוגמא: הכנס 71. הפעולה הסתיימה‬
  }
                        -                         15                   31
                                                                                                       
                       -           11           15           20        31                45

                       -      5    11     13    15     17    20   23   31     32    35   45    47
cs,Technion                          .‫הערה: במידה והרמה העליונה הכילה שני מפתחות אז יש להוסיף רמה חדשה‬
                                                                                ‫05‬
                               ‫הקשר לעצי 2-3‬
 ‫‪Skip lists‬‬




                   ‫נראה כעת כיצד עץ 2-3 הופך להיות רשימת דילוגים דטרמיניסטית.‬
               ‫הטרנספורמציה שנראה נועדה להדגים את הקשר בין שני מבני הנתונים‬
                                                                      ‫שלמדנו.‬
                        ‫בשום מצב אין צורך לממש טרנספורמציה זו בתוכנית מחשב.‬




‫‪cs,Technion‬‬
                                                                                             ‫15‬
                   ‫רשימת דילוגים דטרמיניסטית בהקשר לעצי 2-3‬
 ‫‪Skip lists‬‬




                                                       ‫13‬                           ‫עץ 2-3‬

                                ‫02 ,11‬                                 ‫54‬


                   ‫5‬            ‫51 ,31‬           ‫32‬          ‫53 ,23‬          ‫74‬

               ‫2‬       ‫5‬   ‫11‬    ‫31‬      ‫51‬    ‫32 02‬        ‫53 23 13‬        ‫74 54‬

                                                       ‫13‬         ‫מימוש עץ 2-3 כעץ בינרי:‬

                                 ‫02 ,11‬                                ‫54‬


                   ‫5‬             ‫51 ,31‬          ‫32‬           ‫53 ,23‬          ‫74‬

               ‫2‬       ‫5‬    ‫11‬    ‫31‬      ‫51‬   ‫32 02‬        ‫53 23 13‬        ‫74 54‬
‫‪cs,Technion‬‬
                                                                                                           ‫25‬
                                   ‫רשימת דילוגים דטרמיניסטית (המשך)‬
‫‪Skip lists‬‬




                                                               ‫2‬          ‫חבור הצמתים בכל רמה ושינוי ערכי‬
                                                                            ‫הצמתים הפנימיים נותן ‪.skip list‬‬
                                   ‫2‬                                                ‫13‬


             ‫2‬                     ‫11‬                    ‫02‬               ‫13‬                  ‫54‬

         ‫2‬       ‫5‬       ‫11‬    ‫31‬            ‫51‬        ‫32 02‬           ‫53 23 13‬          ‫74 54‬
                                                                                ‫הוספת איבר ראשון ואיבר סופי.‬
‫‪-‬‬                                                                 ‫2‬


‫‪-‬‬                                      ‫2‬                                                ‫13‬
                                                                                                       ‫‪‬‬
‫‪-‬‬               ‫2‬                      ‫11‬                ‫02‬                   ‫13‬              ‫54‬

‫‪-‬‬           ‫2‬       ‫5‬        ‫11‬        ‫31‬        ‫51‬    ‫32 02‬           ‫53 23 13‬              ‫74 54‬
                                                                                                         ‫35‬
                              ‫רשימת דילוגים דטרמיניסטית (המשך)‬
‫‪Skip lists‬‬




                                                       ‫13‬                                  ‫העץ המקורי.‬

                              ‫02 ,11‬                                       ‫54‬


                 ‫5‬            ‫51 ,31‬             ‫32‬              ‫53 ,23‬              ‫74‬

             ‫2‬       ‫5‬   ‫11‬    ‫31‬      ‫51‬   ‫02‬    ‫32‬        ‫13‬    ‫23‬      ‫53‬    ‫54‬    ‫74‬

                                                                          ‫רשימת דילוגים אקוויוולנטית.‬
‫‪-‬‬                                                     ‫2‬


‫‪-‬‬                              ‫2‬                                          ‫13‬
                                                                                                   ‫‪‬‬
‫‪-‬‬               ‫2‬              ‫11‬               ‫02‬                ‫13‬                ‫54‬

‫‪-‬‬           ‫2‬       ‫5‬   ‫11‬    ‫31‬      ‫51‬   ‫02‬    ‫32‬        ‫13‬    ‫23‬      ‫53‬    ‫54‬    ‫74‬
Skip lists

						
Related docs