1 / 57

תרגול 12:

תרגול 12:. ומחסנית Iterator רשימה מקושרת, תור,. רשימה מקושרת ( Linked List ). רשימה מקושרת הינה קבוצה סדורה של אובייקטים, כאשר כל אובייקט ברשימה מכיל הצבעה לאובייקט הבא. כל אובייקט מהווה חוליה בשרשרת: - קודקוד ברשימה הינו מסוג Link - כל הרשימה נקראת LinkedList. null. Data. Next. Link.

kynton
Download Presentation

תרגול 12:

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. תרגול 12: • ומחסניתIteratorרשימה מקושרת, תור,

  2. רשימה מקושרת (Linked List) רשימה מקושרת הינה קבוצה סדורה של אובייקטים, כאשר כל אובייקט ברשימה מכיל הצבעה לאובייקט הבא. כל אובייקט מהווה חוליה בשרשרת: - קודקוד ברשימה הינו מסוג Link - כל הרשימה נקראת LinkedList null Data Next Link

  3. Data Next Link מחלקה שמייצגת חוליה Link publicclass Link { private Object data; private Link next; public Link(Object data, Link next) { this.data = data; this.next = next; } public Link(Object data) { this(data, null); } public Object getData() { returndata; } publicvoid setData(Object data) { this.data = data; } public Link getNext() { returnnext; } publicvoid setNext(Link next) { this.next = next; } }

  4. מחלקה שמייצגת רשימה משורשרת LinkedList publicclass LinkedList { private Link first; public LinkedList (){ first = null; } public LinkedList (Object data){ first = new Link(data, null); } ... }

  5. מחלקה שמייצגת רשימה משורשרת LinkedList LinkedList first data next null data data next next 5

  6. נוסיף למחלקה את השיטה: נרצה לדעת האם הרשימה שלנו מכילה איברים או לא? אז נוסיף את השיטה הבוליאניתisEmpty() אשר תחזיר true אם הרשימה ריקה, ו-false אחרת. publicboolean isEmpty() { return (first == null); }

  7. נוסיף למחלקה את השיטה: publicvoid addLast(Object data) { Link newLink = new Link(data, null); if (isEmpty()) { first = newLink; } else { Link linkPointer = first; while (linkPointer.getNext() != null) { linkPointer = linkPointer.getNext(); } linkPointer.setNext(newLink); } }

  8. דוגמת שימוש LinkedList lst = new LinkedList(); lst.addLast( "World!"); lst.addLast( "Hello" ); lst.addLast( "Great" ); next data data data next next LinkedList first null null

  9. נוסיף גם למחלקה את השיטה: נוסיף שיטה אשר מסירה את החוליה הראשונה ברשימה ומחזירה את האובייקט המוצבע על ידה. public Object removeFirst(){ Object ans; if (isEmpty()) { ans = null; } else { ans = first.getData(); first = first.getNext(); } return ans; }

  10. המשך דוגמת שימוש lst.removeFirst(); lst.removeFirst(); lst.removeFirst(); next data data data next next LinkedList null first "Hello" "Great" "World!"

  11. המשך דוגמת שימוש lst.removeFirst(); lst.removeFirst(); lst.removeFirst(); next data data next LinkedList null first "Great" "World!"

  12. המשך דוגמת שימוש lst.removeFirst(); lst.removeFirst(); lst.removeFirst(); next data LinkedList null first "World!"

  13. המשך דוגמת שימוש lst.removeFirst(); lst.removeFirst(); lst.removeFirst(); LinkedList null first

  14. נוסיף למחלקה LinkedList את השיטהgetMiddle : • getMiddle • - מהו האיבר האמצעי ברשימה? • - רעיונות לפתרון?

  15. getMiddle public Object getMiddle(){ Object ans; if(isEmpty()) { ans = null; } else { Link current = first; Link jumper = first; while( (jumper != null) && (jumper.getNext() != null) ){ current = current.getNext(); jumper = jumper.getNext().getNext(); } ans = current.getData(); } return ans; } &&

  16. while( (jumper != null) && (jumper.getNext() != null) ){ current = current.getNext(); jumper = jumper.getNext().getNext(); } ans = current.getData(); …

  17. נוסיף למחלקה LinkedList את השיטהcontainsCircles : 2. containsCircles – האם יש מעגלים ברשימה? - האם עלולים להיווצר מעגלים שכאלה? - חידה: כמה מעגלים לכל היותר יכולים להיות ברשימה מקושרת? 17

  18. publicboolean containsCircles() { boolean ans; if(isEmpty()) { ans = false; } else { Link current = first; Link jumper = first; boolean start = true; while(jumper != null && ( current != jumper || start) ){ start = false; current = current.getNext(); jumper = jumper.getNext(); if (jumper != null) jumper = jumper.getNext(); } ans = (jumper != null); } return ans; }

  19. while(jumper != null && ( current != jumper || start) ){ start = false; current = current.getNext(); jumper = jumper.getNext(); if (jumper != null) jumper = jumper.getNext(); }

  20. while(jumper != null && ( current != jumper || start) ){ start = false; current = current.getNext(); jumper = jumper.getNext(); if (jumper != null) jumper = jumper.getNext(); }

  21. while(jumper != null && ( current != jumper || start) ){ start = false; current = current.getNext(); jumper = jumper.getNext(); if (jumper != null) jumper = jumper.getNext(); }

  22. while(jumper != null && ( current != jumper || start) ){ start = false; current = current.getNext(); jumper = jumper.getNext(); if (jumper != null) jumper = jumper.getNext(); }

  23. while(jumper != null && ( current != jumper || start) ){ start = false; current = current.getNext(); jumper = jumper.getNext(); if (jumper != null) jumper = jumper.getNext(); }

  24. while(jumper != null && ( current != jumper || start) ){ start = false; current = current.getNext(); jumper = jumper.getNext(); if (jumper != null) jumper = jumper.getNext(); }

  25. Iterator

  26. Iterator • מידע ונתונים (data) הדרושים לתכנית מחשב נשמרים בתוך מבנה נתונים (data structure). • על מבנה נתונים יש צורך לבצע מספר פעולות, כמו הכנסת נתונים והוצאת נתונים. • אחת הדרכים להוציא נתונים היא לעבור על אוסף הנתונים פריט-מידע אחר פריט-מידע.

  27. Iterator • נרצה שתכונה זו תהיה משותפת למבני נתונים רבים, למשל לרשימה, שראינו זה עתה. • לכן נגדיר ממשק, שאותו כל מבנה נתונים יממש. • נרצה להגיד שמבנה נתונים הוא ניתן למעבר פריט-אחר-פריט, ובאנגלית: Iterable. ב-JAVA קיים הממשק: publicinterface Iterable { /** *Returnsaniteratoroverasetofelements. * *@returnanIterator. */ Iterator iterator(); }

  28. Iterator • יהיה לנו אובייקט שיעזור בתהליך. אובייקט זה יעבור על אוסף הנתונים פריט אחר פריט, לפי סדר מסוים, ובאנגלית:Iterator . ב-JAVA מוגדר ממשק לעבודה עם אובייקט כזה:

  29. publicinterface Iterator { /** *Returnstrueiftheiterationhasmoreelements. *@returntrueiftheiteratorhasmoreelements. */ boolean hasNext(); /** *Returnsthenextelementintheiteration. *@returnthenextelementintheiteration. * @exception NoSuchElementException iteration has no more elements. */ Object next(); /** *Removesfromtheunderlyingcollectionthelastelementreturnedbythe *iterator(optionaloperation) *@exceptionUnsupportedOperationExceptionifthe"remove" *operationisnotsupportedbythisIterator. * *@exceptionIllegalStateExceptionifthe"next"methodhasnot *yetbeencalled,orthe"remove"methodhasalready *beencalledafterthelastcalltothe"next" *method. */ void remove(); }

  30. שימוש ב-Iterator בהמשך נראה כיצד להפוך את המחלקה LinkedList כך שתתמוך ב-Iterator, כרגע נניח שהמחלקה כבר תומכת בו, ועל סמך זאת נעשה שימוש ב-Iterator שמתקבל מהשיטה iterator(), שמובטחת לנו מכיוון ש-LinkedList מממשת את Iterable. publicstaticvoid main(String[] args) { LinkedList lst = new LinkedList(); lst.addLast("Shnitsels"); lst.addLast(“Are"); lst.addLast("Tasty"); Iterator it = lst.iterator(); while (it.hasNext()) { Object currentData = it.next(); System.out.print(currentData); if (it.hasNext()) System.out.print(", "); } System.out.println(); }

  31. דוגמת שימוש while (it.hasNext()) { Object currentData = it.next(); System.out.print(currentData); if (it.hasNext()) System.out.print(", "); } System.out.println(); data data next next LinkedList ListIterator Shnitsels, Are, Tasty currentLink first data next null

  32. מימוש ה-Iterator עבור LinkedList publicclass ListIterator implements Iterator { private Link currentLink; public ListIterator(Link first) { currentLink = first; } publicboolean hasNext() { return ( currentLink != null ); } public Object next() { if (!hasNext()) { thrownew NoSuchElementException(); } Object data = currentLink.getData(); currentLink = currentLink.getNext(); return data; } publicvoid remove() { thrownewUnsupportedOperationException(); } }

  33. מימוש ה-Iterable במחלקה LinkedList עתה נראה כיצד נתמוך ב Iterator במחלקה LinkedList: publicinterface Iterable { /** *Returnsaniteratoroverasetofelements. * *@returnanIterator. */ Iterator iterator(); }

  34. מימוש ה-Iterable במחלקה LinkedList • עכשיו כל מה שנותר לעשות הוא לממש את השיטה iterator() של הממשק Iterable ב LinkedList: publicclass LinkedList implements Iterable{ private Link first; public LinkedList (){ first = null; } … // All methods remain the same public Iterator iterator(){ returnnew ListIterator(first); } }

  35. הערות • Iterator מניח שלא נעשה שינוי באוסף עליו הוא עובר במהלך המעבר. אם נעשה שינוי – האיטרטור איננו במצב חוקי ואין הבטחה לפעולה תקינה שלו. • השיטה ()next מחוייבת לזרוק את החריגה NoSuchElementException במידה ואין יותר אלמנטים באוסף. ( אם לפני כל קריאה ל-next() נוודא ש hasNext() החזיר true אז לא נתקל בחריגה זו). • החריגה: UnsupportedOperationException נזרקת כאשר אנו מחוייבים להכריז שיטה מסויימת (למשל כי היא חלק מממשק) במחלקה שלנו, אך אנו לא תומכים בשיטה זו. לכן בגוף השיטה נזרוק את החריגה.

  36. תור - Queue •  תור (Queue) הוא מבנה נתונים המזכיר תור של בני אדם: האיבר שנכנס ראשון לתור- יוצא ממנו ראשון. • ניתן לראות כקופסה סגורה בעלת 2 פתחים: פתח הכנסה ופתח יציאה. • איבר שנכנס ראשון יוצא ראשון FIFO (FIFO - First In First Out). • שימושים: ניהל תהליכים ע"י מערכת ההפעלה, ניהול תור בבית מרקחת, ...

  37. public interface Queue{ /** *isEmpty-checksifthequeueisemptyornot. *@returntrueifthequeueisempty */ publicboolean isEmpty(); /** *dequeue-removesanobjectfromtheheadofthequeue. * (FIFOorder) *@returnthenextobjectinthequeue. */ public Object dequeue(); /** *enqueue-insertsanobjectintothequeue. *@paramotheobjecttobeenqueued. */ publicvoid enqueue(Object o); }

  38. מימוש תור ע"י רשימה מקושרת publicclass QueueAsList implements Queue { private LinkedList lst; public QueueAsList() { lst = new LinkedList(); } publicboolean isEmpty() { return lst.isEmpty(); } public Object dequeue() { return lst.removeFirst(); } publicvoid enqueue(Object o) { lst.addLast(o); } }

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

  40. המשך import java.util.Scanner; … publicstaticvoid main(String args[]) { Scanner sc = new Scanner(System.in); Queue q = new QueueAsList(); System.out.println("Insert few lines … "); while (sc.hasNextLine()) { String line = sc.nextLine(); q.enqueue( line ); } System.out.println("Printing all the lines back! "); while (!q.isEmpty()) { System.out.println(q.dequeue()); } }

  41. דוגמה נוספת "'WIMBELDON" : 41 רוצים לבצע טורניר טניס

  42. המשך 42 נרצה לממש את השיטה: publicstatic Player simulateTournament(LinkedList playersList) אשר מקבלת רשימה של שחקנים ומבצעת סימולציה של טורניר טניס באופן הבא: * בשלב הראשון השחקנים מתחלקים לזוגות. * מכל זוג עולה המנצח לשלב הבא ושוב השחקנים מתחלקים לזוגות עד שנותר שחקן בודד שהוא המנצח (טורניר נוק אוט).

  43. המשך 43 נממש את השיטה ע"י שימוש בתור – כאשר נאתחל אותו באברי הרשימה, וכל עוד התור מכיל יותר מאיבר אחד נשלוף שני שחקנים מהתור, "ניתן" להם לשחק ואת המנצח נכניס לסוף התור (עבר לסיבוב הבא).

  44. המשך שחקן 4 שחקן 4 שחקן 3 שחקן 2 שחקן 1 שלב 1: שחקן 1 שחקן 3 שחקן 2 שחקן 4 44

  45. המשך שחקן 2 שלב 2: שחקן 4 שחקן 4 שחקן 3 שחקן 2 שחקן 1 שלב 1: שחקן 3 שחקן 4 שחקן 2 45

  46. המשך שחקן 2 שחקן 4 שחקן 4 שלב 2: שחקן 4 שחקן 4 שחקן 3 שחקן 2 שחקן 1 שלב 1: שחקן 2 שחקן 4 46

  47. המשך שלב 3 (המנצח): שחקן 2 שחקן 2 שחקן 4 שחקן 4 שלב 2: שחקן 4 שחקן 4 שחקן 3 שחקן 2 שחקן 1 שלב 1: שחקן 2 47

  48. publicstatic Player simulateTournament( LinkedList playersList) { Queue q = new QueueAsList(); Iterator it = playersList.iterator(); Player winner = null; while (it.hasNext()) { q.enqueue( it.next() ); } while ( ! q.isEmpty() ) { Player first = (Player)q.dequeue(); if (q.isEmpty()) { winner = first; } else { Player second = (Player)q.dequeue(); Player matchWinner = getWinner(first,second); q.enqueue( matchWinner ); } } return winner; } 48

  49. מחסנית (stack) • מחסנית (stack) היא מבנה נתונים שמזכיר מחסנית של רובה: האיבר שנכנס ראשון למחסנית יוצא ממנה אחרון (LIFO - Last In First Out). • ניתן לראות במחסנית קופסה סגורה בעלת פתח יחיד, שדרכו נעשות פעולות הדחיפה והשליפה. • הטיפול דרך פתח יחיד יוצר מצב שבו איבר שנכנס אחרון יוצא ראשון- LIFO . • מחסנית היא שימושית כאשר יש צורך לשמור נתונים בסדר מסוים ולשלוף אותם בסדר הפוך.

  50. ממשק publicinterface Stack { /** *push-addsanelementtothestack. *@paramotheelementedtobeinsertedtothestack. */ publicvoid push (Object o); /** *pop-removesanelementformthestack(LIFOorder). *@returntheelementfromthetopofthestack. */ public Object pop (); /** *isEmpty-checksifthestackisemptyornot. *@returntrueifthereisnomoreelementsinthestack. */ publicboolean isEmpty(); }

More Related