Presentation is loading. Please wait.

Presentation is loading. Please wait.

ليست هاي پيوندي.

Similar presentations


Presentation on theme: "ليست هاي پيوندي."— Presentation transcript:

1 ليست هاي پيوندي

2 ليستهاي پيوندي اشاره گرها ليست ها ليست هاي دايره اي
پشته ها و صفهاي پيوندي چند جمله اي ها روابط هم ارزي ليستهاي دو پيوندي و ليست هاي تعميم يافته

3 مقدمه (bat, cat, sat, vat) مشکلات بازنمايي ترتيبي
ليست مرتب زير را در نظر بگيريد (bat, cat, sat, vat) براي اضافه کردن کلمه mat بايد کلمات sat و vat يک مکان به راست شيفت داده شوند. براي حذف کردن کلمه cat بايد کلمات sat و vat يک مکان به چپ شيفت داده شوند. مشکلات بازنمايي ترتيبي 1- حذف و درج عناصر در آرايه ها بسيار وقت گير است 2- باذخيره کردن هر ليست در آرايه اي با حداکثر اندازه ، حافظه هدر مي رود

4 بازنمايي پيوندي راه حل مناسب : استفاده از بازنمايي پيوندي
عناصر مي توانند در هر جاي حافظه قرار گيرند. در بازنمايي ترتيبي، ترتيب اعضاي ليست با ترتيب نگهداري اعضا در حافظه يکسان است ولي در بازنمايي پيوندي لازم نيست ترتيب اعضاي ليست با ترتيب نگهداري اعضا يکسان باشد. براي دستيابي صحيح به عناصر يک ليست ، بايستي به همراه هر عنصر، آدرس يا موقعيت عنصر بعدي نيز ذخيره شود. بنابراين براي هر عنصر ليست، يک نود وجود دارد که حاوي فيلدهاي داده اي و اشاره گري به عنصر بعدي در ليست مي باشد.

5 شماي حافظه شماي حافظه براي ليستL = (a,b,c,d,e) بازنمايي ترتيبي (آرايه)
بازنمايي پيوندي a b c d e The figures show computer memory. An array uses a contiguous chunk of memory. c a e d b

6 بازنمايي پيوندي اشاره گر در e برابر NULL است.
c a e d b first اشاره گر در e برابر NULL است. از متغير first براي دسترسي به عنصر اول استفاده مي شود.

7 اشاره گرها C به صورت مناسبي از اشاره گرها حمايت مي کند.
دو عملگري که با اشاره گرها به کار مي روند: & the address operator * the dereferencing (or indirection) operator مثال اگر تعريف زير را داشته باشيم int i, *pi; آنگاه i يک متغير صحيح و pi يک اشاره گر به يک متغير صحيح است. و pi = &i; آدرس i را برگردانده و به عنوان مقدار pi نسبت مي دهد.. براي مقدار دهي به i i = 10; or *pi = 10;

8 اشاره گرها هر زمان که نياز به حافظه جديدي باشد مي توان تابعي به نام malloc را فراخواني و مقدار فضاي لازم را درخواست کرد. اگر حافظه لازم وجود داشته باشد ، اشاره گري به ابتداي ناحيه حافظه مورد نياز برگردانده مي شود. زماني که ديگر نيازي به آن حافظه نباشد ، مي توان آن را با فراخواني تابعي به نام free ، آزاد نمود. Request memory Free memory

9 ليست هاي تک پيوندي ليست هاي پيوندي معمولا به وسيله گره هايي متوالي با اتصالاتي که به صورت فلش هايي نشان داده شده اند ارايه مي گردند.

10 ليست هاي تک پيوندي گره ها واقعا در مکانهاي پشت سر هم حافظه قرار نمي گيرند موقعيت گره ها در اجراهاي مختلف مي تواند تغيير کند. Data Field Link Field Node . . . Null ptr chain چرا با استفاده از بازنمايي پيوندي حذف و اضافه ساده تر است؟

11 ليست هاي تک پيوندي براي اضافه کردن کلمه mat بين cat و sat :
1- گره ي استفاده نشده اي را در نظر گرفته ، فرض کنيد که آدرس آن paddr باشد. 2- فيلد داده اين گره را برابر با mat قرار دهيد 3- فيلد اتصال paddr را طوري تنظيم کنيد که به ادرسي که در فيلد اتصال گره حاوي cat مي باشد، اشاره کند 4- فيلد اتصال گره حاوي cat را طوري تنظيم کنيد که به paddr اشاره کند.

12 ليست هاي تک پيوندي حذف mat از ليست
براي انجام اين کار فقط لازم است که عنصر قبل از mat يعني cat را پيدا و فيلد اتصال آنرا طوري تنظيم کنيم که به گره اي اشاره کند که در حال حاضر اتصال گره mat به ان اشاره دارد ما هيچ داده اي را جابجا نکرده ايم و با وجود آنکه فيلد اتصال mat هنوز به sat اشاره مي کند mat ديگر عضو ليست نيست.

13 ليست هاي تک پيوندي يک يا چند فيلد ساختار اشاره گر به همين ساختار هستند
typedef struct list { char data; list *link; } list item1, item2, item3; item1.data=‘a’; item2.data=‘b’; item3.data=‘c’; item1.link=item2.link=item3.link=NULL; Construct a list with three nodes item1.link=&item2; item2.link=&item3; malloc: obtain a node (memory) free: release memory a b c

14 ليست هاي تک پيوندي ptr 10  20 NULL Example [Two-node linked list]:
typedef struct list_node *list_pointer; typedef struct list_node { int data; list_pointer link; }; list_pointer ptr =NULL; Program : Create a two-node list list_pointer create2( ) { /* create a linked list with two nodes */ list_pointer first, second; first = (list_pointer) malloc(sizeof(list_node)); second = (list_pointer) malloc(sizeof(list_node)); second -> link = NULL; second -> data = 20; first -> data = 10; first ->link = second; return first; } ptr 10 20 NULL

15 ليست هاي تک پيوندي اضافه کردن
يک نود با داده 50 به ليست ptr و بعد از node اضافه کنيد. node 20 10 50 NULL temp ptr

16 ليست هاي تک پيوندي Implement Insertion:
void insert(list_pointer *ptr, List_pointer node) { /* insert a new node with data = 50 into the list ptr after node */ list_pointer temp; temp=(list_pointer)malloc(sizeof(list_node)); if(IS_FULL(temp)){ fprintf(stderr, “The memory is full\n”); exit(1); } temp->data=50; temp 50

17 ليست هاي تک پيوندي if(*ptr){ //nonempty list
temp->link = node->link; node->link = temp; } else{ //empty list temp->link = NULL; *ptr = temp; ptr 10 20 NULL node 50 temp

18 ليست هاي تک پيوندي حذف کردن عضوي که node به آن اشاره مي کند را حذف کنيد ptr trial node ptr trial node NULL 10 50 20 ptr

19 ليست هاي تک پيوندي Implement Deletion:
void delete(list_pointer *ptr, list_pointer trail, list_pointer node) { /* delete node from the list, trail is the preceding node ptr is the head of the list */ if(trail) trail->link = node->link; else *ptr = (*ptr)->link; free(node); } ptr trial node 50 10 NULL 20

20 ليست هاي تک پيوندي Get(0) پيمايش (چاپ) يک ليست پيوندي a b c d e first
NULL first desiredNode = first; // gets you to first node return desiredNode->data;

21 ليست هاي تک پيوندي Get(1) پيمايش (چاپ) يک ليست پيوندي a b c d e first
NULL first desiredNode = first->link; // gets you to second node return desiredNode->data;

22 ليست هاي تک پيوندي Get(2) پيمايش (چاپ) يک ليست پيوندي a b c d e first
NULL first desiredNode = first->link->link; // gets you to third node return desiredNode->data;

23 ليست هاي تک پيوندي Get(5) پيمايش (چاپ) يک ليست پيوندي a b c d e first
NULL first desiredNode = first->link->link->link->link->link; // desiredNode = NULL return desiredNode->data; // NULL.element

24 ليست هاي تک پيوندي پيمايش (چاپ) يک ليست پيوندي
Program : Printing a list void print_list(list_pointer first) { printf(“The list contains: “); for ( ; first; first= first->link) printf(“%4d”, first->data); printf(“\n”); }

25 پشته ها و صف هاي پيوندي هنگامي که چندين صف و پشته وجود داشته باشد روش ترتيبي کارايي براي بازنمايي آنها وجود ندارد. در بازنمايي پيوندي جهت اشاره گر براي پشته و صف به صورتي است که عمليات حذف کردن و اضافه کردن گره ها در انها به اساني انجام شود. به اساني مي توانيد يک گره را به بالاي پشته اضافه و يا از آن حذف کنيد. به اساني مي توانيد يک گره به آخر صف اضافه کنيد يا عمل اضافه کردن و حذف کردن را در اول صف انجام دهيد (هر چند اضافه کردن گره در اول صف معمولا انجام نمي شود)

26 پشته ها و صف هاي پيوندي بازنمايي n پشته top item link NULL ... Stack

27 پشته ها و صف هاي پيوندي Push in the linked stack ...
void add(stack_pointer *top, element item){ /* add an element to the top of the stack */ Push stack_pointer temp = (stack_pointer) malloc (sizeof (stack)); if (IS_FULL(temp)) { fprintf(stderr, “ The memory is full\n”); exit(1); } temp->item = item; temp->link = *top; *top= temp; link temp item link top link ... NULL

28 پشته ها و صف هاي پيوندي Pop from the linked stack ...
element delete(stack_pointer *top) { /* delete an element from the stack */ Pop stack_pointer temp = *top; element item; if (IS_EMPTY(temp)) { fprintf(stderr, “The stack is empty\n”); exit(1); } item = temp->item; *top = temp->link; free(temp); return item; temp top item link link link ... NULL

29 پشته ها و صف هاي پيوندي بازنمايي n صف ... Queue front item link
NULL ... Queue rear اضافه کردن حذف کردن

30 پشته ها و صف هاي پيوندي اضافه کردن به صف پيوندي ... front link link
rear NULL temp item NULL

31 پشته ها و صف هاي پيوندي حذف کردن از صف پيوندي ... temp front item link
rear NULL

32 پشته ها و صف هاي پيوندي راهکار ارائه شده براي مسائل n-stack و m-queue هم از نظر محاسباتي و هم از نظر مفهومي ساده هستند. لازم نيست براي ايجاد فضاي خالي پشته ها و يا صف ها شيفت داده شوند. تا زماني که حافظه وجود داشته باشد مي توان از ان استفاده کرد.

33 عمليات روي ليست هاي پيوندي
اضافه کردن يک گره به انتهاي ليست پيوندي void attach(list_pointer first, list_pointer last, List_pointer newnode) { if(first==0) first=last=newnode; else last->link=newnode; last=newnode; } فرض مي کنيم عضو داده اي last وجود دارد که به گره آخر ليست پيوندي اشاره مي کند

34 عمليات روي ليست هاي پيوندي
معکوس کردن ليست پيوندي void Invert(list_pointer first) { list_pointer p=first, q=0, r=0; //q trails p while( p) { r=q; q=p; //r trails q p=p->link; //p moves to next node q->link=r; //link q to preceding node } first =q; براي ليست به طول m زمان اجرا o(m)

35 عمليات روي ليست هاي پيوندي
اتصال دو زنجير void Concatenate(list_pointer first_a, list_pointer first_b) { if (!first_a) { first_a=first_b; return;} if (first_b) { for (list_pointer p=first; p->link; p=p->link); no body p->link=first_b; } زمان اجرا بر حسب طول زنجير اول خطي است

36 زنجير با گره سر a b c d e NULL headerNode حال اضافه/حذف از سمت چپ (انديس صفر) متفاوت با حذف و اضافه کردن بقيه نودها نيست و کد حذف/ اضافه ساده تر مي شود.

37 زنجير خالي با گره سر headerNode NULL

38 ليست دايره اي a b c d e firstNode براي بررسي اينکه ايا اشاره گر current به گره آخر ليست دايره اي اشاره مي کند به جاي مقايسه (current->link==0) مقايسه ي (current->link==first) انجام مي شود. الگوريتم هاي حذف/ اضافه کردن از/ به ليست دايره اي بايد تضمين کند که فيلد اشاره گر گره آخر به گره اول ليست اشاره کند.

39 ليست دايره اي مي خواهيم گره جديدي به اول ليست بالا اضافه کنيم a b c d
e firstNode مي خواهيم گره جديدي به اول ليست بالا اضافه کنيم بايد اشاره گر گره آخر (گره اي که حاوي e است) را تغيير دهيم. بايد تا پيدا نشدن گره آخر در طول ليست حرکت کنيم.

40 ليست دايره اي a b c d e lastNode
هنگامي که از گره سر استفاده نمي کنيم بهتر است اشاره گر دسترسي به ليست دايره اي به جاي گره اول به گره آخر ليست اشاره کند. در اينصورت اضافه کردن يک گره در اول و يا در آخر ليست دايره اي در مدت زمان ثابتي انجام مي شود.

41 ليست دايره اي اضافه کردن گره اي که x به آن اشاره مي کند در اول ليست
void InsertFront(list_pointer last, list_pointer x) // insert the node pointed at by x at the front of the circular list // last points to the last node in the list { if (!last) { // empty list last=x; x->link=x; } else { x->link=last->link; last->link=x; زمان اجرا O(1) است

42 ليست دايره اي اضافه کردن گره اي که x به آن اشاره مي کند در انتهاي ليست
void InsertRear(list_pointer last, list_pointer x) // insert the node pointed at by x at the rear of the circular list // last points to the last node in the list { if (!last) { // empty list last=x; x->link=x; } else { x->link=last->link; last->link=x; last=x; } تفاوت با کد قبلي زمان اجرا O(1) است

43 چند جمله اي ها بازنمايي چند جمله ايها با ليست هاي پيوندي
ai ها ضرايب غير صفر و ei ها توانهاي صحيح غير منفي هستند به قسمي که em-1 > em-2 > … > e1 > e0 ≧ 0 . هر عبارت با يک گره که شامل سه فيلد ضريب، توان و اشاره گر به گره بعدي است نشان داده مي شود.

44 چند جمله اي ها coef expon link typedef struct poly_node *poly_pointer;
int coef; int expon; poly_pointer link; }; poly_pointer a,b,d; coef expon link

45 جمع چند جمله اي ها فرض کنيم که a و b اشاره گرهايي به ابتداي چند جمله اي ها باشند. اگر توان دو چند جمله اي با هم برابر باشد ، ضرايب با هم جمع مي شوند و گره جديدي تشکيل مي شود ، همچنين اشاره گرها را به گره هاي بعدي در a و b حرکت مي دهيم. اگر توان چند جمله اي a کمتر از توان متناظر در چند جمله اي b باشد، آنگاه يک جمله مشابه اين جمله ايجاد و آنرا به نتيجه ، يعني d ، اضافه مي کنيم و اشاره گر را به جمله بعدي در b منتقل مي کنيم. اگر a-> expon >b- > expon باشد عملي مشابه را بر روي a انجام مي دهيم .

46 جمع چند جمله ايها d = a+b

47 جمع چند جمله ايها

48 جمع چند جمله اي ها void attach(float coefficient, int exponent, poly_pointer *ptr){ /* create a new node with coef = coefficient and expon = exponent, attach it to the node pointed to by ptr. Ptr is updated to point to this new node */ poly_pointer temp; temp = (poly_pointer) malloc(sizeof(poly_node)); /* create new node */ if (IS_FULL(temp)) { fprintf(stderr, “The memory is full\n”); exit(1); } temp->coef = coefficient; /* copy item to the new node */ temp->expon = exponent; (*ptr)->link = temp; /* attach */ *ptr = temp; /* move ptr to the end of the list */

49 جمع چند جمله اي ها تحليل جمع چند جمله اي ها
الگوريتم جمع چند جمله اي با فاکتور ثابت بهينه است. تحليل جمع چند جمله اي ها جمع ضرايب 0  additions  min(m, n) where m (n) denotes the number of terms in A (B). مقايسه توان ها extreme case: em-1 > fm-1 > em-2 > fm-2 > … > e1 > f1 > e0 > f0 m+n-1 comparisons ايجاد گره جديد براي d extreme case: maximum number of terms in d is m+n m + n new nodes summary: O(m+n)

50 چند جمله اي ها e(x) = a(x) * b(x) + d(x) poly_pointer a, b, d, e; ...
a = read_poly(); b = read_poly(); d = read_poly(); temp = pmult(a, b); e = padd(temp, d); print_poly(e); read_poly() print_poly() padd() psub() pmult() temp براي ذخيره يم مقدار مياني استفاده شده است با بازگرداندن گره هاي اين چند جمله اي مي توان از گره هاي آن براي نگهداري چندجمله ايهاي ديگر استفاده کرد.

51 چند جمله اي ها حذف يک چند جمله اي void erase (poly_pointer *ptr){
/* erase the polynomial pointed to by ptr */ poly_pointer temp; while ( *ptr){ temp = *ptr; *ptr = (*ptr) -> link; free(temp); }

52 نمايش چند جمله ايها با ليست دايره اي
با استفاده از ليست دايره اي به جاي زنجير مي توانيم تمام گره هاي لست را به صورت کارايي ازاد کنيم. مثال نمايش ptr = 3x14+2x8+1 به صورت ليست دايره اي ptr 3 14 2 8 1

53 نمايش چند جمله ايها با ليست دايره اي
بايد چند جمله اي صفر را به صورت يک حالت خاص در نظر بگيريم. براي اجتناب از چنين حالت خاصي مي توانيم در هر چند جمله اي يک گره سر تعريف کنيم. هر چند جمله اي، چه چند جمله اي صفر يا غير صفر، يک گره اضافي دارد عضوهاي داده expon و coef براي اين گره معني ندارند.

54 اضافه کردن چند جمله ايها به صورت دايره اي
اضافه کردن چند جمله ايها به صورت دايره اي /* head node */ /*a->expon=-1, so b->expont = -1 */ فيلد expon از گره سر را برابر -1 قرار مي دهيم حال اگر تمام گره هاي a بررسي شوند a->expona=-1 خواهد شد و از انجا که b->expon>=-1 است بقيه جملات b در اجراي بعدي دستور case کپي خواهد شد همين مطلب در مورد گره هاي b قبل از a نيز صادق است /* link to the first node */

55 ليست دايره اي با ذخيره گره هايي که حذف شده اند به صورت زنجير، يک الگوريتم حذف کارا براي ليست هاي دايره اي به دست مي آوريم. به جاي استفاده از توابع malloc و free از تابع هاي get_node و ret_node استفاده مي کنيم. ... avail NULL List of freed nodes

56 ليست دايره اي هرگاه احتياج به گره جديدي داشته باشيم ليست آزاد را بررسي مي کنيم. اگر اين ليست خالي نباشد آنگاه از يکي از گره هاي موجود در آن استفاده مي کنيم. فقط وقتي ليست خالي است از دستور malloc براي ايجاد گره جديد استفاده مي کنيم.

57 ليست دايره اي برگرداندن يک گره
avail متغيري از نوع listNode * است که به زنجيري از گره هايي که حذف شده اند اشاره مي کند. اين زنجير يا ليست را ليست حافظه آزاد مي ناميم. در آغاز avail برابر NULL است. اضافه کردن ptrبه ابتداي ليست

58 حذف يک ليست دايره اي ليست دايره اي را مي توان در زمان ثابت (O(1) ) مستقل از تعداد گره هاي ليست حذف کرد.    ptr temp avail    NULL

59 جمع چند جمله اي ها فرض کنيم که a و b اشاره گرهايي به ابتداي چند جمله اي ها باشند. اگر توان دو چند جمله اي با هم برابر باشد ، ضرايب با هم جمع مي شوند و گره جديدي تشکيل مي شود ، همچنين اشاره گرها را به گره هاي بعدي در a و b حرکت مي دهيم. اگر توان چند جمله اي a کمتر از توان متناظر در چند جمله اي b باشد، آنگاه يک جمله مشابه اين جمله ايجاد و آنرا به نتيجه ، يعني d ، اضافه مي کنيم و اشاره گر را به جمله بعدي در b منتقل مي کنيم. اگر a-> expon >b- > expon باشد عملي مشابه را بر روي a انجام مي دهيم .

60 روابط هم ارزي رابطه انعکاسي رابطه متقارن رابطه متعدي
رابطه ≡ روي هر مجموعه S ، رابطه هم ارزي گفته مي شود اگر و تنها اگر داراي خواص انعکاسي ، تقارن و تعدي روي S باشد. مثال: رابطه ”برابر است با“ يک رابطه هم ارزي است زيرا : x = x است . از x = y نتيجه گرفته مي شود که y = x مي باشد x = y و y = z نتيجه مي دهد که x = z است . رابطه انعکاسي for any member x, x ≡ x رابطه متقارن for any two members x and y, if x ≡ y, then y ≡ x. رابطه متعدي for any three members x, y, and z, if x ≡ y and y ≡ z, then x ≡ z.

61 روابط هم ارزي با استفاده از خواص يک رابطه مي توان اعضاي مجموعه اي که اين رابطه بر روي آن تعريف شده است را به چنديد کلاس هم ارزي افراز کرد. دو عضو x و y از s در يک کلاس هم ارزي قرار مي گيرند اگر و فقط اگر x ≡ y مثال: اگر ما اعضاي 0 تا 11 با روابط زير را داشته باشيم 0  4, 3  1, 6  10, 8  9, 7  4, 6  8, 3  5, 2  11, 11  0 مي توانيم آنها را به 3 کلاس هم ارزي زير افراز کنيم: {0, 2, 4, 7, 11};{1, 3, 5};{6, 8, 9,10}

62 روابط هم ارزي مراحل تعيين کلاس هاي هم ارزي مرحله اول: مرحله دوم:
زوج هاي هم ارزي (i,j)، خوانده و ذخيره مي شود. مرحله دوم: از 0 شروع کرده و تمام زوج هايي که به شکل (0,j)، مي باشد پيدا شده و چاپ مي گردد. اين مرحله ادامه پيدا مي کند تا همه ي اعضاي کلاس هم ارزي شامل 0 پيدا شده و چاپ گردد. حال عضوي که هنوز چاپ نشده پيدا شده و مراحل بالا براي ان تکرار مي گردد.

63 روابط هم ارزي //Program to find equivalence classes void main(void){
short int out[MAX_SIZE]; node_pointer seq[MAX_SIZE]; node_pointer x, y, top; int i, j, n; printf(“Enter the size (<=%d) ”, MAX_SIZE); scanf(“%d”, &n); for(i=0; i<n; i++){ /*initialize seq and out */ out[i] = TRUE; seq[i] = NULL; } /* Phase 1 */ /* Phase 2 */ #include <stdio.h> #define MAX_SIZE 24 #define IS_FULL(ptr) (!(ptr)) #define FALSE 0 #define TRUE 1 typedef struct node *node_pointer; typedef struct node { int data; node_pointer link; };

64 روابط هم ارزي مرحله اول: خواندن و ذخيره زوج هاي هم ارزي (i,j)
[0] 11 4 NULL [1] 3 NULL [2] 11 NULL [3] 5 1 NULL [4] 7 NULL Insert x to the top of lists seq[i] [5] 3 NULL [6] 8 10 NULL [7] 4 NULL [8] 6 9 NULL Insert x to the top of lists seq[j] [9] 8 NULL [10] 6 NULL [11] 2 NULL 0  4, 3  1, 6  10, 8  9, 7  4, 6  8, 3  5, 2  11, 11  0

65 روابط هم ارزي مرحله دوم:
از 0 شروع کرده و تمام زوج هايي که به شکل (0,j)، مي باشد پيدا شده و چاپ مي گردد. همه ي j ها در کلاس هم ارزي 0 هستند. با توجه به خاصيت تعدي از تمام زوجهايي که به صورت (j,k) هستند نتيجه مي شود k در همان کلاس 0 است. اين مرحله ادامه پيدا مي کند تا همه ي اعضاي کلاس هم ارزي شامل 0 پيدا شده و چاپ گردد.

66 روابط هم ارزي Push( j) x=x->link m=Pop(); x=seq[m];

67 روابط هم ارزي Phase 2 New class: 0 11 4 7 2 x y i= 1 j= 4 7 11 4 2 11
j= 4 7 11 4 2 11 [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] Phase 2 out: top [0] 11 4 NULL [1] 3 NULL [2] 11 NULL [3] 5 1 NULL [4] 7 NULL [5] 3 NULL [6] 8 10 NULL [7] 4 NULL [8] 6 9 NULL [9] 8 NULL [10] 6 NULL [11] 2 NULL New class: 0 11 4 7 2

68 روابط هم ارزي تحليل تابع هم ارزي فاز اول فاز دوم
مقدار دهي اوليه به seq و out O(n) پردازش هر زوج ورودي O(m) O(n+m) فاز دوم هر گره حداکثر يک بار در پشته قرار مي گيرد. از انجا که 2m گره وجود دارد و حلقه for، n بار اجرا مي شود زمان اجراي اين مرحله O(n+m) است تابع بيان شده با ضريب ثابت بهينه است. فضاي لازم براي اين الگوريتم 0(m + n ) است

69 ليست هاي دو پيوندي ليست هاي تک پيوندي بعضي از مشکلات را ايجاد مي کند زيرا فقط مي توانيم در جهت پيوندها حرکت کنيم. مثال تنها راه يافتن گره ماقبل ptr پيمايش از ابتداي ليست مي باشد. براي حذف يک گره دلخواه بايد آدرس گره قبل را بدانيم. اگر نيازمند پيمايش ليست از هر دو جهت باشيم بهتر است از ليست دو پيوندي استفاده کنيم. ... NULL ptr ?

70 ليست دو پيوندي يک گره در يک ليست دو پيوندي حداقل سه فيلد داده اي دارد:
فيلد data فيلد llink (اشاره گر به چپ ) فيلد rlink ( اشاره گر به راست ) ليست دوپيوندي مي تواند دايره اي باشد يا دايره اي نباشد. مي تواند داراي گره س باشد يا نباشد. typedef struct node *node_pointer; typedef struct node{ node_pointer llink; element item; node_pointer rlink; };

71 ليست دو پيوندي مثال ليست دوپيوندي دايره اي با گره سر
ليست دوپيوندي دايره اي خالي با گره سر فرض کنيد که ptr به گره اي دلخواه در ليست دوپيوندي اشاره کند آنگاه ptr = ptr -> llink -> rlink = ptr -> rlink -> llink

72 ليست دو پيوندي اضافه کردن گره در يک ليست دايره اي دوپيوندي Head node
llink item rlink New node

73 ليست دو پيوندي حذف کردن گره در يک ليست دايره اي دوپيوندي Head node
llink item rlink deleted node

74 ليست هاي تعميم يافته تعريف: ليست تعميم يافته دنباله اي متناهي از n عضو است در آن ها يک عضو ساده يا ليست است. به عضو هايي که ساده نيستند زير ليست گويند. نام تمام ليست ها با حروف بزرگ نمايش داده مي شود و از حروف کوچک براي نمايش زير ليست ها استفاده مي شود. اگر n>=1 باشد آنگاه ابتدا يا اول ليست (head) و انتها يا آخر ليست (tail) نام دارد.

75 ليست هاي تعميم يافته the null or empty list, its length is zero.
D = ( ) a list of length two; its first element is the atom 'a' and its second element is the linear list (b,c). A = (a, (b,c)) a list of length three whose first two elements are the lists A, the third element the null list. B = (A,A,( )) a recursive list of length two. C corresponds to the infinite list C = (a,(a,(a, C = (a, C) head (A) = 'a', tail (A) = ((b,c)). head (B)) = A, tail (B)) = (A, ( )) head (tail(B)) = A, tail (tail(B)) = (( ))

76 ساختار گره يک ليست تعميم يافته
Data|dlink Tag=false| true ساختار گره يک ليست تعميم يافته link enum Boolean {false, true}; Struct GenListNode { GenListNode *link; Boolean tag; union { char data; GenListNode *dlink; }; يک ليست تعميم يافته با يک اشاره گر GenListNode * first

77 نمايش ليست هاي عمومي

78 نمونه کاربرد ليست هاي عمومي
فرض کنيد مي خواهيم چند جمله ايهاي چند متغيره مانند مثال زير را بازنمايي کنيم x10 y3 z2 + 2x8 y3 z2 + 3x8 y2 z2 + x4 y4 z + 6x3 y4 z + 2yz راهکار: استفاده از ساختاري مانند عيب : چند جمله ايهاي با چند متغير مختلف نيازمند تعداد مختلفي فيلد است که باعث بروز مشکلات متعددي در رابطه با نمايش ترتيبي چن جمله ايها مي شود

79 نمونه کاربرد ليست هاي عمومي
P(x,y,z)= =x10 y3 z2 + 2x8 y3 z2 + 3x8 y2 z2 + x4 y4 z + 6x3 y4 z + 2yz =((x10 + 2x8)y3 + 3x8y2)z2 + ((x4 + 6x3)y4 + 2y)z

80 نمونه کاربرد ليست هاي عمومي
ساختار نود براي چند جمله اي enum Triple {var, ptr, no} Struct PolyNode { PolyNode *link; int exp; Triple trio; union { Char vble; PolyNode *dlink; int coef; };

81 نمونه کاربرد ليست هاي عمومي
مثال P= 3x2y var y Trio vble exp link ptr 1 Trio dlink exp link x no 3 2

82 الگوريتم بازگشتي براي ليست ها
کپي يک ليست غير بازگشتي که در آن هيچ زير ليست مشترکي وجود ندارد. GenListNode *copy (GenListNode *p) { /* copy the nonrecursive list with no shared sublists pointed at by p */ GenListNode *q=0; If (p) { q=new GenListNode; q->tag=p->tag; If (!p->tag ) q->data=p->data; else q->dlink= copy( p->dlink); q->link=copy(p->link); } return q; زمان اجراي الگوريتم o(m) يا خطي است . يک کران بالا براي حداقل عمق بازگشتي يا معادل آن تعداد مکان هاي مورد نياز پشته ي بازگشتي m يعني تعداد کل گره ها است که براي A=((((((a)))))) قابل دستيابي است

83 الگوريتم بازگشتي براي ليست ها
برابري دو ليست: ليست ها بايد ساختار يکسان داشته و عضوهاي داده اي متناظرشان نيز بايد داده هاي يکساني داشته باشند int equal (GenListNode *s, GenListNode *t) { int x; if ( !s ) && ( !t ) return 1; if ( s && t && ( s->tag==t->tag) ) if ( !s->tag) if (s->data == t->data ) x=1; else x=0; else x=equal (s->dlink, t->dlink); if (x) return equal (s->link , t->link); } return 0; زمان اجراي الگوريتم خطي است .

84 الگوريتم بازگشتي براي ليست ها
عمق يک ليست: عمق ليست خالي برابر صفر و در حالت کلي

85 الگوريتم بازگشتي براي ليست ها
عمق ليست int depth(GenListNode *s) { if ( !s ) return 0; GenListNode *p=s; int m=0; while (p) { if (p->tag) { int n= depth( p->dlink); if (m<n) m=n; } p=p->link; return m+1;

86 تعداد دفعات ارجاع به ليست
در ليست هايي که ليست مشترک دارند هرگاه بخواهيم گره اي را در اول ليست اضافه يا از آن حذف کنيم مشکلاتي را در کار ايجاد مي کند علاوه بر ان مي توان از فيلد data/dlink گره هاي سر يراي نگهداري تعداد دفعات ارجاع به ليست مربوطه استفاه کرد. 2 در اين ساختار مي توان فيلد tag را اصلاح کرد تا 3 مقدار ممکن 0، 1 و 2 را اختيار کند. 0= data 1= dlink 2= ref 2 2 2 2 2

87 حذف يک ليست به صورت بازگشتي
تنها يک واحد از تعداد دفعات ارجاع کم مي شود. تنها اگر تعداد دفعات ارجاع برابر صفر باشد گره هاي ليست به صورت فيزيکي به حافظه بر گردانده مي شود. void delete(GenListNode *x) { X->ref - -; if (!x ->ref ) GenListNode *y =x; //traverse top level of x; while (y-> link) { y=y-> link; if (y->tag ==1) delete (y-> dlink) ; } y-> link =av; //attach top- llevel nodes to av list av=x; }

88 حذف يک ليست به صورت بازگشتي
در ليست هاي بازگشتي تعداد دفعات ارجاع هيچگاه صفر نمي شود. اين مطلب در مورد بازگشتي غير مستقيم هم صادق است مثال حذف R و سپس S در شکل زير 2 2


Download ppt "ليست هاي پيوندي."

Similar presentations


Ads by Google