דף הבית >> זיכרון דינמי>> הגדרת זיכרון עבור אוביקטים>>רשימות מקושרות>>תיאור הפונקציות

תיאור הפונקציות

( )list כפונקציה בונה המקבלת עבור אובייקט מסוג phone ,שם פרטי ,שם משפחה ומספר טלפון ,ומבצעת הקצאה דינמית , כך ש head יצביע לעבר האובייקט. שים לב !עפ"י צורת האתחול , כאשר מגדירים רשימה מגדירים גם את האיבר הראשון שלה. ( )find_place פונקציה זו מקבלת שם משפחה ומוצאת את המקום אשר אחריו יש להכניס את האובייקט החדש. הבדיקה היא עפ"י הא"ב.הפונקציה insert משתמשת בפונקציה זו אם נרצה להכניס את האובייקט המכיל את הטלפון של danny robas ,מקומו יהיה אחרי george Michael ולפני mark twain ,ולכן הערך המוחזר ע"י הפונקציה ( )find_place יהיה מחוון לאובייקט המכיל את george Michael .

 

דרך פעולת הפונקציות

הפונקציה מגדירה שני מחוונים לאובייקט מסוג phone ,tamp ו prep שני מחוונים מאוחלים ל head ,כך שהם מצביעים לאיבר הראשון .tamp מקודם לאיבר הבא ברשימה, בכל פעם שהלולאה מבוצעת ע"י הפקודה tamp=tamp->next .prep נמצא באיבר אחד לפני tamp ,כיוון שהוא מקבל את ערכו של tamp לפני ש tamp מקודם.הלולאה בודקת בכל איטר ציה אם שם משפחה אשר בtamp גדול משם המשפחה אשר אותו קיבלה הפונקציה כפרמטר . כאשר הוא גדול יותר , סימן ,שעברנו את המקום באחד, ולכן צריך להחזיר את המחוון לאיבר הקודם .הדבר מבוצע ע"י החזרת המחוון prev. נבדוק את מקרה הקצה .אם איבר שמעונינים להכניס לרשימה גדול משאר האיברים , אזי הלולאה תסתיים ע"י כך ש tmp יגיע לסוף ,ויהיה שווה לnull .במקרה כזה prev יצביע על האיבר האחרון ,וזהו באמת המקום שלאחריו יש להכניס את האיבר החדש .אם האיבר החדש יהיה אף קטן מן האיבר הראשון . יוחזר מצביע על האיבר הראשון .מכוון שכך מטופל מקרה זה באופן מיוחד בפונקציה ( )insert .

( )insert תפקידה של הפונקציה הוא לקבל אובייקט חדש ולהכניסו לרשימה .הפונקציה מגדירה מחוון לאובייקט phone בשם tmp .מחוון זה מקבל בעזרת הפונקציה find_place את המקום שלאחריו יש להכניס את האובייקט , ואח"כ הוא אכן מוכנס לשם .

תיאור ההכנסה .

הפקודה p->next=tmp->next משרשרת את האיבר החדש המוצבע ע"י P לפני האיבר אשר נמצא אחרי האיבר המוצבע ע"י tmp לאחר מכן ,צריך ש tmp->next יצביע על האיבר החדש , ודבר זה אכן מבוצע ע"י הפקודה tmp->next=p .

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

if (strcmp (p ->last_name,head->last_name)<0)
 {
 tmp=head;
 head=p;
 p->next=tmp;
 return ( );
 }

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

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

if (!strcmp(last, head->last_name))
 {
 tmp=head;
 head=head->next;
 delete tmp;
 return (1) ;
 }

( )print פונקציה זו מדפיסה את כל הרשימה .הביצוע הוא ע"י לולאת for ומחוון ל phone בשם tmp . המחוון tmp מאותחל לראש הרשימה ומקודם ע"י הפקודה tmp =tmp->next .תנאי העצירה הוא tmp!=null תנאי זה אומר שהגענו לסוף הרשימה.

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

הדרך היא ליצור שני מחוונים ,ולשמור את המקום של האיבר הבא ,לפני שמוחקים את הנוכחי.


#include <iostream.h>
#include "phone.h"
#include "List1.h"
main()
{
	char last[15],first[15];
    long num;
    List1 *l1=new List1("Lennon","John",456641);
    phone *ph1=new phone("Haim","Moshe",345765);
    phone *ph2=new phone("Rabin","Itzhak",467323),*phone_ptr;
    l1->insert(ph1);
    l1->insert(ph2);
    l1->print();
    l1->del("Haim");
    cout<<"after deleting\n";
    l1->print();
     cout<<"input last name first name and phone number\n";
    do{
     cin>>last>>first>>num;
	phone_ptr=new phone(last,first,num);
	l1->insert(phone_ptr);
     }
   while(num);

    l1->print();
  delete l1;
  return 0;
  }				  
				  

הפלט:

Haim moshe 345765
Lennon john 456641
Rabin itzhak 467323

Total number of objects are 3
Destructing phone number 3

Haim moshe 345765
After deleting
Lennon john 456641
Rabin itzhak 467323

Total number of objects are 2
Input last name first name and phone number

Bush george 384774
Lennon john 456641
Lennon john 345589
Michael george 345778
Rabin itzhak 467323
Robas danny 0
Twain mark 347876

Total number of objects are 7
Destructing phone number 7

Bush george 384774
Destructing phone number 7
Lennon john 456641
Destructing phone number 6
Lennon john 345589
Destructing phone number 5
Michael george 345778
Destructing phone number 4
Rabin itzhak 467323
Destructing phone number 3
Robas danny 0
Destructing phone number 2
Twain mark 347876
Destructing phone number 1


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


ll->insert(ph1);
ll->insert(ph2);

לאחר מכן מודפסת הרשימה ע"י הפקודה ll->print( ) .nהפלט בשלב זה:


Haim       moshe   345765
Lennon    john      456641
Rabin       itzhak    467323    


Total number of objects are 3
 

לאחר הדפסת הרשימה נמחק האיבר בעל שם המשפחה "haim",ושוב מודפסת הרשימה .

Destructing phone number   3


Haim       moshe   345765
After deleting
Lennon    john      456641
Rabin       itzhak    467323    


Total number of objects are 2



ההודעה על מחיקת האובייקט נתקבלה ע"י הפונקציה ההורסת של phone. לאחר מחיקת האובייקט ישנה לולאת do_while אשר מקבלת נתונים מלוח המקשים ומכניסה אותם לרשימה .הלולאה מסתיימת כאשר מכניסים מספר טלפון 0 .

Bush        george    384774
Lennon    john       345589
Michael   george    345778
Twain      mark       347876
Robas      danny          0


בסוף הכנסת הנתונים שוב מודפסת הרשימה .

Bush        george    384774
Lennon    john       456641
Lennon    john       345589
Michael   george    345778
Rabin       itzhak     467323    
Robas      danny          0
Twain      mark       347876

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


לסיכום:

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