2 שאלות במבנה נתונים:

  • פותח הנושא mob2
  • פורסם בתאריך

mob2

New member
2 שאלות במבנה נתונים:

שאלה 1: It is possible to convert any binary search tree with n nodes to any other BST with n nodes using rotations. The number of rotations required for this in the worst case is i. 0(log n) ii. 0(n) iii. 0(n log n) אני יודע בוודאות שחסם מלמטה הוא חסם לינארי השאלה היא אם הוא גם החסם העליון. הסיבה שאני חושב שזה nlogn היא משום שכל כל איבר בעץ אפשר לבצע logn רוטציות מקסימום (להעלות אותו מלמטה למעלה או להוריד אותו מהשורש למטה ומכיוון שיש לנו n איברים זה נראה כמו nlogn אולי אני טועה ודברים מתקזזים. הערה: השאלה שואלת מהו החסם ההדוק על מספר הרוטציות ולא עלות הרוטציות (שהיא גם ככה קבועה). שאלה 2: (a) (10 pt) Describe a data structure that supports the following operations, with the above running time constraints: insert(key) O(log(n)) delete(key) O(log(n)) getMax(), getMin() O(1) extractMax(), extractMin() O(log(n)) Build(ArrayA) O(n) אוקי פה אני תקוע כי רציתי להשתמש בתור קדימיות שהוא סוג של היפ אבל הבעיה היא שבהיפ אי אפשר לאתר איבר בזמן של logn למען הסר ספק המתודות extractMax(), extractMin() פשוט מוציאות את האיבר המקסימלי/מינימלי לעומת האלה שמעליהן שרק מחזירות את הערך המסימלי.מינימלי המתודה Build(ArrayA) מקבלת מערך של איברים ובונה ממנו את טיפוס הנתונים. תודה לכל העונים...
 

skies

New member
לגבי מבני הנתונים

פשוט תחזיק עץ AVL ושני ערימות אחת ערימת מינימום ואחת ערימת מקסימום שאתה מכניס איבר תכניס אותו גם לעץ וגם לערימות להוצאה אתה פשוט מוחק אותו מהעץ ומהערימות (עושה Heapify down/up) ואז זה Log n לאיתור איברים פשוט תמצא אותם בעץ
 

mob2

New member
תודה

זה נראה לי קצת בזבזני להחזיק 3 מבנים שונים אבל כנראה שאין ברירה אחלה, תודה רבה
 

skies

New member
זה לא בזבזני

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

mob2

New member
נראה לי שיש בעיה במה שאתה מציע...

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

skies

New member
...

את האיבר אתה מוצא בתוך העץ זה לוקח Log n עכשיו,שמצאת את האיבר בעץ הוא יחזיק גם מצביע לאיבר בערימה אתה הולך למקום של האיבר בערימה,מחליף אותו עם האיבר האחרון בערימה זה O(1) אתה מקטין את גודל הערימה ל N-1 ואח"כ במקום ההוא שהחלפת אתה מפעיל פעם אחת heapify down ופעם שניה אתה מפעיל heapify up שניהם לוקחים Log n ככה שאתה לא חורג במהלך כל הפרוצדורה הזאת מסיבוכיות של log n
 

mob2

New member
מצביע לאיבר בערימה?

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

mob2

New member
אם האיברים שעובדים איתם הם..

לא אינסטנסים שנוצרו (כלומר אינסטנסים של אובייקטים) למשל כמו int אז אי אפשר להחזיק להם מצביעים ואז הפתרון בעייתי. הפתרון ישים רק אם האיברים שעובדים איתם באמת יכולים להחזיק רפרנסים (כלומר הם אינסטנסים של אובייקטים).
 

skies

New member
תעשה משהו כזה

איבר יהיה מבנה שבו יש 2 שדות,מצביע לתא בערימה וערך בעץ יהיו מצביעים למבנה הזה כל איבר בערימה הוא מצביע לאיבר שלו (יש הצבעה דו כיוונית בין האיבר לערימה ובין הערימה לאיבר) ככה שאתה מכניס משהו לערימה אתה בסך הכל משחק עם הרשימת פוינטרים שיש בערימה ולא צריך לעדכן כלום בעץ
 

mob2

New member
הכל עובד טוב חוץ מדבר אחד לעזאזל!

מתודת הבנייה צריכה לעבוד בזמן לינארי ואני לא מצליח לחשוב איך לבנות את העץ בזמן לינארי למישהו יש כיוון?
 

vinney

Well-known member
שמע

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

mob2

New member
המתרגל נתן לי רמז...

הוא טוען שאני צריך לשקול מה לעשות עם n/2 האברים האחרונים במערך בשביל להשיג זמן ריצה לינארי. אני רואה את השימוש בחצי האיברים האחרונים (שהם למעשה יהיו עלים) רק מתי שבונים היפ. שכן ראיתי כבר הוכחה שבניית היפ בעזרת heapify עובדת בזמן לינארי אבל מה בקשר בין מה שהוא אמר לבניית עץ איי וי אל, אין לי מושג. הוא טוען בתוקף שיש בזה משהו, לי נראה שלא. נראה לי שאני מרים ידיים
 

2good2b

New member
האם DELETE מקבל מפתח או מצביע לאיבר?

שאלה חשובה - אם הוא מקבל מצביע ניתן לממש הנ"ל באמצעות 2 ערימות...
 

vinney

Well-known member
לפי הניסוח, insert וdelete מקבלים אותו דבר

כך שזה לא יכול להיות מצביע. אבל אני נוטה לחשוב שהניסוח לא משהו, וזה אכן שאלת שתי הערימות הסטנדרטית.
 

mob2

New member
טוב המתרגל טעה לדעתי בגלל

שעל מנת לבנות עץ בזמן לינארי צריך לבצע מיון השוואה בזמן שנמוך מnlogn סתירה.
 

2good2b

New member
2

נסה להוכיח כי כל עץ אפשר להעביר לעץ שרוך שמאלי תוך ביצוע N-1 רוטציות לכל היותר. מכיוון שפעולת הרוטציות היא פעולה הפיכה זה מכסה את 2 הצדדים (העברה של העץ הראשון לרשימת שרוך, והפיכת רשימת השרוך לעץ השני)
 
למעלה