Nir Adar

Σχετικά έγγραφα
ל הזכויות שמורות לדפנה וסטרייך

מבני נתונים (234218) 1

עצי 2-3 תזכורת: בנים. דוגמאות: Chapter 19: B trees ( ) Chapter 15: Augmenting data structures ( )

Nir Adar גירסה 1.00 עמוד 1

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

לדוגמה: במפורט: x C. ,a,7 ו- 13. כלומר בקיצור

חורף תש''ע פתרון בחינה סופית מועד א'

פתרון תרגיל 5 מבוא ללוגיקה ותורת הקבוצות, סתיו תשע"ד

פתרון תרגיל 8. מרחבים וקטורים פרישה, תלות \ אי-תלות לינארית, בסיס ומימד ... ( ) ( ) ( ) = L. uuruuruur. { v,v,v ( ) ( ) ( ) ( )

מבני נתונים ואלגוריתמים תרגול #3 נושאים: תור קדימויות/ערימה, עצים

אלגוריתמים בתורת הגרפים חלק ראשון

תרגול פעולות מומצאות 3

השאלות..h(k) = k mod m

פתרון תרגיל מרחבים וקטורים. x = s t ולכן. ur uur נסמן, ur uur לכן U הוא. ur uur. ur uur

תרגול מס' 6 פתרון מערכת משוואות ליניארית

דוגמה: יהי T עץ בינארי כפי שמתואר בציור הבא:

מתמטיקה בדידה תרגול מס' 13

סיכום- בעיות מינימוםמקסימום - שאלון 806

Hash Tables (המשך) ערבול (Hashing)

תורת הגרפים - סימונים

כלליים זמן: S מחסנית, top(s) ראש המחסנית. (Depth First Search) For each unmarked DFS(v) / BFS(v) רקורסיבי. אלגוריתם :BFS

I. גבולות. x 0. מתקיים L < ε. lim אם ורק אם. ( x) = 1. lim = 1. lim. x x ( ) הפונקציה נגזרות Δ 0. x Δx

סדרות - תרגילים הכנה לבגרות 5 יח"ל

שדות תזכורת: פולינום ממעלה 2 או 3 מעל שדה הוא פריק אם ורק אם יש לו שורש בשדה. שקיימים 5 מספרים שלמים שונים , ראשוני. שעבורם

אלגברה רלציונית ניר אדר

Logic and Set Theory for Comp. Sci.

( )( ) ( ) f : B C היא פונקציה חח"ע ועל מכיוון שהיא מוגדרת ע"י. מכיוון ש f היא פונקציהאז )) 2 ( ( = ) ( ( )) היא פונקציה חח"ע אז ועל פי הגדרת

תרגיל 13 משפטי רול ולגראנז הערות

אסימפטוטיים תוכנית הקורס עצי AVL עצי 2-3 עצי דרגות סיבוכיות משוערכת מיון מיון שימושים: גרפים איסוף אשפה

צעד ראשון להצטיינות מבוא: קבוצות מיוחדות של מספרים ממשיים

מבני נתונים ויעילות אלגוריתמים

לוגיקה ותורת הקבוצות פתרון תרגיל בית 8 חורף תשע"ו ( ) ... חלק ראשון: שאלות שאינן להגשה נפריד למקרים:

TECHNION - ISRAEL INSTITUTE OF TECHNOLOGY DEPARTMENT OF COMPUTER SCIENCE סמסטר אביב תשס"ו מס' סטודנט:

אוניברסיטת בר אילן מבני נתונים תרגולים מרצה: פרופ' שמואל טומי קליין סמסטר ב', תש"ע

מבני נתונים 08a תרגול 8 14/2/2008 המשך ערמות ליאור שפירא

מבני נתונים ויעילות אלגוריתמים

פתרון תרגיל 6 ממשוואות למבנים אלגברה למדעי ההוראה.

1 תוחלת מותנה. c ארזים 3 במאי G מדיד לפי Y.1 E (X1 A ) = E (Y 1 A )

יסודות לוגיקה ותורת הקבוצות למערכות מידע (סמסטר ב 2012)

קבוצה היא שם כללי לתיאור אוסף כלשהו של איברים.

ניהול תמיכה מערכות שלבים: DFfactor=a-1 DFt=an-1 DFeror=a(n-1) (סכום _ הנתונים ( (מספר _ חזרות ( (מספר _ רמות ( (סכום _ ריבועי _ כל _ הנתונים (

תוכן הפרק: ,best case, average case דוגמאות 1. זמן - נמדד באמצעות מס' פעולות סיבוכיות, דוגמאות, שיפור בפקטור קבוע האלגוריתם. וגודלם. איטרטיביים. לקלט.

{ : Halts on every input}

לוגיקה ותורת הקבוצות מבחן סופי אביב תשע"ב (2012) דפי עזר

c ארזים 26 בינואר משפט ברנסייד פתירה. Cl (z) = G / Cent (z) = q b r 2 הצגות ממשיות V = V 0 R C אזי מקבלים הצגה מרוכבת G GL R (V 0 ) GL C (V )

(2) מיונים השאלות. .0 left right n 1. void Sort(int A[], int left, int right) { int p;

השאלות ידי מצביעים לילדים.

[ ] Observability, Controllability תרגול 6. ( t) t t קונטרולבילית H למימדים!!) והאובז' דוגמא: x. נשתמש בעובדה ש ) SS rank( S) = rank( עבור מטריצה m

x a x n D f (iii) x n a ,Cauchy

מיונים א': מיון (Sorting) HeapSort. QuickSort תור עדיפויות / ערימה

2 יח"ל ) השלמה ל - 5 יח"ל) (50 נקודות) מעבר חוקי, ו-'שקר' אחרת.

' 2 סמ ליגרת ןורתפ םיפרגה תרותב םימתירוגלא דדצ 1 : הלאש ןורתפ רבסה תורעה

מבני נתונים ואלגוריתמים תרגול #11

gcd 24,15 = 3 3 =

אלגוריתמים / תרגיל #1

שאלה 1 V AB פתרון AB 30 R3 20 R

עץץץץ AVL. עץ AVL הוא עץ חיפוש בינארי שמקיים את התנאי הבא: לכל צומת x בעץ גורם האיזון של x הוא 1, 0, או 1-. הגדרה: במילים אחרות: לכל צומת x בעץ,

brookal/logic.html לוגיקה מתמטית תרגיל אלון ברוק

= 2. + sin(240 ) = = 3 ( tan(α) = 5 2 = sin(α) = sin(α) = 5. os(α) = + c ot(α) = π)) sin( 60 ) sin( 60 ) sin(

הגדרה: קבוצת פעילויות חוקית היא קבוצה בה כל שתי פעילויות

תכנון אלגוריתמים 2016 עבודה 1 שאלה 1 פתרון נתונות שתי בעיות. יש למצוא: אורך מסלול קצר ביותר המתחיל באחד מן הקודקודים s 1,..., s k ומסתיים ב t.

דף פתרונות 7 נושא: תחשיב הפסוקים: צורה דיסיונקטיבית נורמלית, מערכת קשרים שלמה, עקביות

מבחן מועד ב' בהצלחה! אנא קיראו היטב את ההוראות שלהלן: ודאו כי כל עמודי הבחינה נמצאים בידכם.

הגדרה: מצבים k -בני-הפרדה

מתכנס בהחלט אם n n=1 a. k=m. k=m a k n n שקטן מאפסילון. אם קח, ניקח את ה- N שאנחנו. sin 2n מתכנס משום ש- n=1 n. ( 1) n 1

חידה לחימום. כתבו תכappleית מחשב, המקבלת כקלט את M ו- N, מחליטה האם ברצוappleה להיות השחקן הפותח או השחקן השappleי, ותשחק כך שהיא תappleצח תמיד.

logn) = nlog. log(2n

חלק א' שאלה 3. a=3, b=2, k=0 3. T ( n) היותר H /m.

co ארזים 3 במרץ 2016

מבני נתונים הגבלת אחריות פרק - 1 אלגוריתמי מיון ואנליזה אסימפטוטית. מיון בועות Sort Bubble מאת : סשה גולדשטיין,

לוגיקה ותורת הקבוצות פתרון תרגיל בית 4 אביב תשע"ו (2016)

אלגוריתמים בתורת הגרפים חלק שני

תאריך עדכון אחרון: 27 בפברואר ניתוח לשיעורין analysis) (amortized הוא טכניקה לניתוח זמן ריצה לסדרת פעולות, אשר מאפשר קבלת

תורת הקבוצות תרגיל בית 2 פתרונות

תשובות מלאות לבחינת הבגרות במתמטיקה מועד ג' תשע"ד, מיום 0/8/0610 שאלונים: 315, מוצע על ידי בית הספר לבגרות ולפסיכומטרי של אבירם פלדמן

תכנון דינאמי. , p p p והמטריצה המתקבלת היא בגודל

רשימת בעיות בסיבוכיות

מתמטיקה בדידה תרגול מס' 5

מבני נתונים מבחן מועד ב' סמסטר חורף תשס"ו

אלגברה ליניארית (1) - תרגיל 6

אלגוריתמים 1, סמסטר אביב 2017

לוגיקה ותורת הקבוצות מבחן סופי אביב תשע"ד (2014) דפי עזר

תרגול 1 חזרה טורי פורייה והתמרות אינטגרליות חורף תשע"ב זהויות טריגונומטריות

פרק 13 רקורסיה רקורסיה רקורסיה רקורסיות פשוטות: חישוב עצרת. תמונת המחסנית ב-() factorial רקורסיות פשוטות: פיבונאצ'י

מודלים חישוביים פתרון תרגיל 5

מבני נתונים עצים שיעור 7

אלגברה ליניארית 1 א' פתרון 7

מודלים חישוביים תרגולמס 5

אינפי - 1 תרגול בינואר 2012

שיטות אנליזה לניתוח זמנים משוערך Amortized Time Analysis

פתרון תרגיל 4 יסודות מבני נתונים סמסטר א' תשע"ה שאלה 1:

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

אלגברה ליניארית 1 א' פתרון 2

תרגיל 7 פונקציות טריגונומטריות הערות

. {e M: x e} מתקיים = 1 x X Y

םינותנ ינבמ (הנכות ידימלתל)

אלגוריתמים בתורת הגרפים חלק רביעי

מבני נתונים מבחן מועד א' סמסטר אביב תשס"ו

הרצאה תרגילים סמינר תורת המספרים, סמסטר אביב פרופ' יעקב ורשבסקי

סיכום לינארית 1 28 בינואר 2010 מרצה: יבגני סטרחוב מתרגלת: גילי שול אין המרצה או המתרגלת קשורים לסיכום זה בשום דרך.

Transcript:

גירסה 28.6.2003-1.00 רשימת דילוגים מסמך זה הורד מהאתר. אין להפיץ מסמך זה במדיה כלשהי, ללא אישור מפורש מאת המחבר. מחבר המסמך איננו אחראי לכל נזק, ישיר או עקיף, שיגרם עקב השימוש במידע המופיע במסמך, וכן לנכונות התוכן של הנושאים המופיעים במסמך. עם זאת, המחבר עשה את מירב המאמצים כדי לספק את המידע המדויק והמלא ביותר. כל הזכויות שמורות ל Nir Adar Email: underwar@hotmail.com Home Page: אנא שלחו תיקונים והערות אל המחבר. -1-

רשימת דילוגים עבור עצים מאוזנים, מימוש פעולות המילון נעשה בזמן (n O(log במקרה הגרוע ביותר. מימוש הפעולות אינו טריוויאלי, במיוחד כאשר יש צורך לתמוך גם בפעולות הדורשות לשמור בכל צומת אינפורמציה ייחודית (כמו (rank ולעדכן אותה. נציג מבנה נתונים בעל מימוש פשוט יותר, שלא דורש איזונים לאחר הכנסה/הוצאה. בתמורה לכך, ביצוע פעולות המילון יעשה בזמן (n O(log בממוצע. ראינו כבר שעצי חיפוש ללא פעולות איזון יכולים לשמש למימוש פעולות המילון בזמן (n O(log בממוצע. בניתוח שעשינו הנחנו שהוכנסו n איברים לעץ, לפיכך קיימות!n פרמוטציות להכנסתם. הממוצע של גובה!n העצים שנוצרו הוא (n.o(log בניתוח זה ישנן מספר בעיות. ראשית, בדרך כלל ההסתברות להופעת פרמוטציה בקלט איננה אחידה. שנית, מבנה הנתונים שנוצר תלוי בסדר הכנסת הנתונים. אדם/תהליך המחבל במערכת יכול להכניס סדרת נתונים כך שהפעולות יבוצעו בזמן האיטי ביותר. במבנה שנציג - רשימת דילוגים, בעיות אלו נפתרות. הפעולות וזמן ביצוען תלוי בהגרלות שעושה המחשבים, ולא בסדר הכנסת הנתונים. הממוצע מחושב לפי ההגרלות ולא לפי הנחות על ההסתברות של הקלטים. אלגוריתם כזה נקרא אלגוריתם רנדומלי. נביט ברעיון של מבנה הנתונים. ניקח רשימה ממוינת של איברים. חיפוש איבר בסוף הרשימה הוא יקר (מבחינת פעולות). 2 11 12 15 21 2 25 26 36 65 כדי לזרז את החיפוש (פי 2), נוסיף מדריך - תת רשימה של כל איבר שני. ממדריך זה יהיה אפשר להגיע לאיבר המתאים ברשימה הראשונה. 2 12 21 25 36 2 11 12 15 21 2 25 26 36 65 כדי לזרז את החיפוש במדריך נוסיף רמה נוספת: 2 21 36 2 12 21 25 36 2 11 12 15 21 2 25 26 36 65 כך נמשיך עד לרמה n log בה יהיה איבר בודד. כדי לפשט את האלגוריתמים המממשים רשימת דילוגים, נהוג להוסיף צומת דמה בתחילת כל שורה ברשימת הדילוגים, וכן צומת אחת בסוף רשימת הדילוגים, שכל השורות יסתיימו בה. -2-

2 21 36 2 12 21 25 36 2 11 12 15 21 2 25 26 36 65 אורך מסלול החיפוש במהלך החיפוש, במעבר מרמה לרמה אנו עוברים על פני שני מצביעים לכל היותר. לפיכך, אורך המסלול הוא. 2logn מספר הצמתים הכולל אינו עולה על. 2n פעולת חיפוש ברשימת דילוגים (id) p מקבל את כתובתו של הצומת העליון השמאלי ביותר. כל עוד לא הגעת אל תחתית רשימת הדילוגים או לא הגעת אל סופה, בצע: כל עוד p.right.id id בצע:. p p.right אם לא הגעת אל תחתית הרשימה, בצע. p p.down אם p.id = id החזר את p. אחרת החזר: "האיבר המבוקש איננו ברשימת הדילוגים"..1.2.3..5 פעולת ההכנסה ברשימת דילוגים חפש את k. אם k נמצא, סיים. שמור מצביע לצומת הימני ביותר בכל רמה במסלול החיפוש. הוסף צומת חדש ברמה התחתונה ביותר וקבע את המפתח להיות k. לפי סדר הרמות מלמטה למעלה: הגרל מטבע.toss() אם יוצא 0: הוסף צומת חדש מעל הרמה הנוכחית וקבע את המפתח בו להיות k. אם יוצא 1: עצור. אם ברמה העליונה הוגרל 0, הוסף רמה חדשה..1.2.3..5 פעולת הוצאה מרשימת דילוגים מצא את האיבר בעל המפתח k. הוצא איבר זה מכל הרמות בהן הוא מופיע..1.2 מספר הצמתים ברשימת דילוגים מספר הצמתים הממוצע ברשימת דילוגים הוא 2n, כאשר n הוא מספר המפתחות במבנה. אורך מסלול החיפוש הממוצע. L 2log n+ 2 2 האורך הממוצע L של מסלול חיפוש ברשימת דילוגים עם n מפתחות מקיים זמן ביצוע הפעולות חיפוש, הכנסה, והוצאה מרשימת דילוגים נעשים בזמן ממוצע החיפוש מתבצעים (1)O צעדים. (n O(log כיוון שבכל צעד על מסלול -3-

רשימת דילוגים דטרמיניסטית כאשר אנו משתמשים ברשימת הדילוגים הרנדומלית, הפעולות וזמן ביצוען תלוי בהגרלות שעושה המחשבים, ולא בסדר הכנסת הנתונים. בממוצע אנו מקבלים זמני ביצוע פעולות של (n.o(log אולם, רשימת הדילוגים הרנדומלית מתבססת על כך שמנוע יצירת המספרים האקראיים של המחשב מתנהג "כמצופה". במידה והמצב הוא לא כזה, עשויה רשימת הדילוגים להראות כרשימה מקושרת פשוטה, וסיבוכיות הפעולות עליה יהיו ליניאריות במקרה הגרוע בהתאם. נרצה למצוא דרך להשתמש ברשימת דילוגים, בעזרתה נוכל להגיע לזמני ביצוע פעולות של (n O(log במקרה הגרוע. כידוע - קיימים מבני נתונים, עצי חיפוש, המאפשרים לממש מילון ב- (n - O(log עצי,AVL עצי 2-3, עצי red-black ועוד. אנו מחפשים אלטרנטיבה למבנים אלו עקב המימוש המסובך שלהם. נציג פתרון המשתמש ברשימת דילוגים בהדרגתיות, תוך כדי הצגת הדרך כיצד פותח הפיתרון הסופי בו נשתמש. נקודת ההתחלה הגדרה רשימת דילוגים L תכונה רשימת דילוגים מאוזנת בשלמות אם היא מקיימת את התנאים הבאים: 1. L היא רשימת דילוגים. 2. עבור k טבעי קבוע כלשהו, מתקיים כי כל איבר k -י בגובה h ברשימת הדילוגים מופיע גם בגובה 1+h ברשימת הדילוגים. עבור רשימת דילוגים מאוזנת בשלמות, פעולת חיפוש מתבצעת בזמן לוגריתמי. אם זאת, איננו יכולים לבצע פעולות הכנסה או הוצאה על הרשימה, מבלי לפגוע בהיותה רשימת דילוגים מאוזנת בשלמות. לפיכך, נחליש מעט את הדרישה השניה, על ידי שינוי הביטוי "עבור כל איבר k י- ". הגדרה תהי רשימת דילוגים L בעלת n מפתחות. נאמר ששני אלמנטים ברשימה מקושרים אם קיים מצביע אחד או יותר ביניהם. בהינתן שני אלמנטים מקושרים, אחד בגובה h בדיוק ) 1< h ), והשני בגובה h המרווח ביניהם להיות מספר האלמנטים ברמה ה- 1 h הקיימים ביניהם. לדוגמא, נביט ברשימת הדילוגים הבאה: או יותר, נגדיר את 2 21 36 2 21 2 36 2 11 12 15 21 2 25 26 36 65 המרווח בין 21 ל- 36 הוא 1, המרווח בין 2 ל- 36 הוא 2, ואילו המרווח בין 2 ל- 21 הוא 0. --

הגדרה רשימת דילוגים L תיקרא רשימת דילוגים דטרמינסטית 1-2 אם מתקיים: 1. L היא רשימת דילוגים. 2. המרווח בין כל שני אלמנטים ב- L הוא 1 או 2. טענה בין רשימת דילוגים לעצי 2-3 יש קשר הדוק. קיימת התאמה חד חד ערכית ועל בין כל עץ 2-3 לרשימת דילוגים דטרמיניסטית 1-2. נציג את האלגוריתם המשמש להפיכת עץ 2-3 לרשימת דילוגים דטרמינסטית 1-2 על ידי דוגמא. ניקח את עץ 2-3 הבא: 3 11 21 55 6 13 15 2 37 1 72 6 11 13 15 21 2 3 37 1 55 72 מימוש של העץ כעץ בינרי ייראה כך: 3 11 21 55 6 13 15 2 37 1 72 6 11 13 15 21 2 3 37 1 55 72 חיבור הצמתים בכל רמה ושינוי ערכי הצמתים הפנימיים נותן :skip-list 3 11 21 3 55 6 11 13 15 21 2 3 37 1 55 72-5-

נוכל להוסיף גם מפתחות התחלה וסיום, ולקבל את רשימת הדילוגים האקוויולנטית הבאה: 3 11 21 3 55 6 11 13 15 21 2 3 37 1 55 72 מימוש פעולות מילון על רשימת הדילוגים חיפוש - חיפוש מפתח ברשימת דילוגים דטרמינסטית נעשה באופן זהה לחיפוש מפתח ברשימת דילוגים רנדומלית. הכנסה - הכנסה נעשית על ידי חיפוש המפתח המבוקש, והכנסת המפתח ברמה התחתונה של רשימת הדילוגים, בסוף מסלול החיפוש. בשלב זה ייתכן מצב בו יהיו שלושה אלמנטים בגובה 1 הנמצאים ברצף. נפתור בעיה זו על ידי העלאת האמצעי ביניהם לרמה 2. אם כעת נוצרו ברמה 2 שלושה אלמנטים ברצף, נעלה את האמצעי ביניהם לרמה 3, וכך הלאה. אם יהיו שלושה איברים ברצף ברמה העליונה, ניצור רמה חדשה, ונשים בה את האמצעי ביניהם. הערה: בניגוד לרשימת דילוגים רנדומלית, המפתח שמוכנס אינו בהכרח זה שמשוכפל ברמה מעל. הוצאה - מחיקת איברים נעשית בדרך אנלוגית לגמרי לפעולת המחיקה בעץ 2-3. סיבוכיות הפעולות חיפוש - פעולת חיפוש נעשית ב- (n.o(log אלמנטים גדלים לרמה נוספת. log( n + 2) הכנסה - ניתן לראות כי בפעולת הכנסה, לכל היותר 1 סיבוכיות הפעולה תלוייה במימוש רשימת הדילוגים. סיבוכיות פעולה זו תלויה בצורה בה אנו מממשים את רשימת הדילוגים. מימוש מקובל הוא שלכל מפתח מתאים מערך של מצביעים, המציין את הצמתים היוצאים ממנו אל צמתים אחרים. במקרה שאנו מגדילים את הרמה של המפתח, מוקצה מערך בגודל גדול יותר, ומערך המצביעים המקורי משוכפל אליו. 2 אם רשימת הדילוגים ממומשת כך, אזי פעולת ההכנסה תיקח (n,θ(log מכיוון שייתכן כי עבור כל הכנסה נאלץ להעתיק מערך. 2 הוצאה - באופן זהה להכנסה, פעולת מחיקה עלולה לקחת (n.θ(log סיבוכיות מקום (ללא הוכחה) מספר הצמתים ברשימת דילוגים דטרמינסטית 1-2 חסום על ידי (n )O. שיפור הסיבוכיות של האלגוריתם על ידי מימוש רשימת דילוגים כשורות של רשימות מקושרת, אנו מסוגלים להגדיל או להקטין את רמתו של צומת בזמן (1)O, ועל ידי כך לשפר את סיבוכיות הזמן של פעולות ההכנסה וההוצאה להיות (n.o(log עם זאת, מימוש כזה מכפיל את כמות הזיכרון הנדרשת עבור המצביעים של המבנה. -6-

מימוש של רשימת דילוגים 1-2 נציג בדפים הבאים מימוש של רשימת דילוגים 1-2 בשפת ++C. כל איבר ברשימת הדילוגים הוא מסוג.CSkipNode הגדרת ומימוש CSkipNode להלן: CSkipNode.h #ifndef _CSKIPNODE_H #define _CSKIPNODE_H #include <iostream.h> // for NULL // Skip-List Node class CSkipNode public: // Consturctors CSkipNode(int key) : ikey(key), SkipNext(NULL), SkipDown(NULL) CSkipNode(int key, CSkipNode* vnext, CSkipNode* vdown) : ikey(key), SkipNext(vNext), SkipDown(vDown) // Virtual Desturctor, to support inheritance virtual ~CSkipNode() /////////////////////////////////////// // Skip List Functions // /////////////////////////////////////// // Get the next node in the skip list CSkipNode *GetSkipNext() const return SkipNext; ; // Get the lower node in the skip list CSkipNode *GetSkipDown() const return SkipDown; ; // Set the next node in the skip list void SetSkipNext(CSkipNode *next) SkipNext = next; ; // Set the lower node in the skip list void SetSkipDown(CSkipNode *down) SkipDown = down; ; int GetKey() const return ikey; ; private: CSkipNode *SkipNext, *SkipDown; ; int ikey; -7-

inline bool operator ==(const CSkipNode& test1, const CSkipNode& test2) return test1.getkey() == test2.getkey();; inline bool operator >(const CSkipNode& test1, const CSkipNode& test2) return test1.getkey() > test2.getkey(); inline bool operator <(const CSkipNode& test1, const CSkipNode& test2) return!(operator >(test1, test2)); #endif רשימת הדילוגים עצמה תמומש במחלקה.CSkipList המחלקה תומכת ב- Insert ו- Search בלבד. ניתן לממש גם את,Remove על ידי שימוש באלגוריתמים של עץ 2-3, אולם פעולה זו מסובכת יחסית. CSkipList.h #ifndef _CSKIPLIST_H #define _CSKIPLIST_H #include "general.h" #include "CSkipNode.h" #include <iostream.h> class CSkipList public: /////////////////////////////////////// // SkipList Standard Functions // /////////////////////////////////////// // Consturctor. // Action: Initalize the Skip List. CSkipList(); // Desturctor. // Action: Free all the elements in the skip list ~CSkipList(); -8-

// Insert // Insert new node to the skip list. The given pointer is // saved in the list. It doesn't create new copy of it. // We assume that the id doesn't exists in the skiplist // Gets: The node to insert // Returns: Error code Result Insert(CSkipNode *node); // Search // Search for node with given id. // Gets: id // Returns: pointer to the node if exists, else NULL. CSkipNode* Search(int id); private: CSkipNode *Header, *Tail; ; #endif // Insert1 // Insert new node to the skip list. The given pointer is // saved in the list. It doesn't create new copy of it. // Gets: Node to start working on, the node to insert // Returns: true if a node was added on the last level bool Insert1(CSkipNode* Current, CSkipNode *node); CSkipList.cpp מימוש המחלקה: #include "CSkipList.h" #include "CSkipNode.h" #include <iostream.h> // for NULL #include <limits.h> #include <stdlib.h> // Consturctor. // Action: Initalize the Skip List. CSkipList::CSkipList() try // Create the header node Tail = new CSkipNode(INT_MAX, NULL, NULL); -9-

Header = new CSkipNode(INT_MIN, Tail, NULL); Tail->SetSkipDown(Tail); Tail->SetSkipNext(Tail); catch(...) // Handle memory problems cerr << "Error: Not enough memory" << endl; exit(1); // Desturctor. // Action: Free all the elements in the skip list CSkipList::~CSkipList() CSkipNode* First = Header; while (First!= NULL) CSkipNode* next = First; // save the next line First = First->GetSkipDown(); // free all the current line while (next!= Tail) CSkipNode* temp = next->getskipnext(); delete next; next = temp; delete Tail; // Insert // Insert new node to the skip list. The given pointer is saved in the // list. It doesn't create new copy of it. // We assume that the id doesn't exists in the skiplist // Gets: The node to insert // Returns: Error code Result CSkipList::Insert(CSkipNode *node) try if (Insert1(Header, node) && Header->GetSkipNext()- >GetSkipNext()->GetSkipNext()!= Tail) CSkipNode* MidNode = Header->GetSkipNext()- >GetSkipNext(); CSkipNode* NewNode = new CSkipNode(MidNode- >GetKey(), Tail, MidNode); -10-

CSkipNode* NewHeader = new CSkipNode(INT_MIN, NewNode, Header); Header = NewHeader; return SUCCESS; catch(...) // Handle memory problems cerr << "Error: Not enough memory" << endl; exit(1); return FAILURE; // Insert1 // Insert new node to the skip list. The given pointer is saved in the // list. It doesn't create new copy of it. // Gets: The node to insert // Returns: true if a node was added on the last level bool CSkipList::Insert1(CSkipNode* Current, CSkipNode *node) for (; Current->GetSkipNext()->GetKey() <= node- >GetKey(); Current = Current->GetSkipNext()); if (Current->GetSkipDown() == NULL) node->setskipnext(current->getskipnext()); Current->SetSkipNext(node); return true; if (!Insert1(Current->GetSkipDown(), node)) return false; CSkipNode* temp; temp = Current->GetSkipDown()->GetSkipNext()- >GetSkipNext(); if (temp->getskipnext()->getkey() < Current- >GetSkipNext()->GetKey()) CSkipNode* New2 = new CSkipNode(temp->GetKey(), Current->GetSkipNext(), temp); Current->SetSkipNext(New2); return true; return false; // Search // Search for node with given id. // Gets: id // Returns: pointer to the node if exists, else NULL. -11-

CSkipNode* CSkipList::Search(int key) CSkipNode *scan = Header; while (scan!= NULL && scan!= Tail) while (scan->getskipnext()->getkey() <= key) scan = scan->getskipnext(); if (scan->getkey() == key && scan->getskipdown() == NULL) return scan; scan = scan->getskipdown(); return NULL; -12-

רשימת דילוגים דטרמינסטית 1-3 הגדרה רשימת דילוגים L תיקרא רשימת דילוגים דטרמינסטית 1-3 אם מתקיים: 1. L היא רשימת דילוגים. 2. המרווח בין כל שני אלמנטים ב- L הוא 2 1, או 3. רשימה כזו ניתן להמיר באופן חד-חד ערכי לעץ 2-3-. עבור עצי 2-3- קיים אלגוריתם שבעזרתו אנו מסוגלים לבצע את ההכנסה ואת התיקונים הדרושים תוך כדי שאנו יורדים מטה במסלול החיפוש, וכך נחסך מאיתנו הצורך לנהל מחסנית של מסלול החיפוש. נאמץ גישה זו בפעולת ההכנסה לרשימת דילוגים 1-3: בעץ פעולת הכנסה, נפצל כל מרווח של 3 לשני מרווחים של 1. בדרך זו נבטיח שהמבנה שומר על שמורת רשימת הדילוגים הדטרמינסטית, עם וגם ללא הצומת החדש שנוסיף. באופן מפורט יותר: נתחיל את פעולת ההכנסה בראש הרשימה. אם המרווח של הצומת ממנה אנו רוצים לרדת הוא 1 או 2, אנו פשוט יורדים. אם המרווח הוא 3, ראשית נשכפל את האיבר האמצעי אל הרמה הנוכחית, תוך כדי שאנו יוצרים על ידי כך שני מרווחים בגודל 1, ואז נרד. פעולת המחיקה נעשית באופן דומה: נתחיל את חיפוש האיבר בראש רשימת הדילוגים. לפני שנרד נרצה שכל מרווח במסלול החיפוש יהיה מרווח חוקי, אולם גדול מהמינימום, כך שאם נמחק איבר מאותה רמה, היא תשאר במצב חוקי. נעשה זאת על ידי איחוד צומת עם השכן, או על ידי שאילה מהשכן. אלגוריתם: נתחיל את החיפוש בראש הרשימה. אם המרווח של הצומת בה אנו הולכים לרדת הוא 2 או 3, אנו פשוט יורדים. אם המרווח הוא 1, נמשיך בצורה הבאה: נסמן את המרווח ב- G. אם G הוא לא המרווח האחרון ברמה הנוכחית, אז אם המרווח שאחריו, G, הוא בגודל 1, אנו מאחדים את G ואת G. (על ידי הנמכת האלמנט המפריד ביניהם). אם G הוא בגודל 2 או 3, אנו משאילים ממנו צומת (על ידי הנמכת האלמנט המפריד בין G ל- G והגבהת האיבר הראשון של G). אם G הוא המרווח האחרון, אנו מאחדים אותו, או מלווים, מהמרווח שלפניו. אנו ממשיכים בדרך זו עד שאנו מגיעים לרמה התחתונה, ממנה אנו מוחקים את האיבר. מכיוון שהאלגוריתם שלנו לא מאפשר מרווחים באורך 1 במסלול החיפוש, אנו נשארים עם רשימת דילוגים חוקית. עם זאת, ישנו יוצא דופן, והוא שאם אנו מוחקים את האיבר, עלול להיווצר מרווח יותר גדול מ- 3. בעיה זו איננה קיימת עבור עץ 2-3-. לפיכך - כאשר אנו מממשים רשימת דילוגים זו, לא נוכל להימנע משמירת מסלול החיפוש במחסנית. לאחר מחיקת האיבר, נעבור על מסלול החיפוש מלמטה למעלה. אם המרווח גדול מ- 3, (כלומר הוא 5,, או 6), נרים את אחד האיברים על מנת להפוך את המרווח למרווח חוקי. אלגוריתמים אלו עומדים בסיבוכיות זמן של (n.o(log אלגוריתם ההכנסה פשוט יותר מזה של רשימת דילוגים 1-2, ואילו אלגוריתם ההוצאה מסובך יותר, עקב מקרי הקצה הרבים הקיימים. EOF -13-