990 likes | 1.16k Views
ليست هاي پيوندي. تعريف ليست پيوندي Link List. تعريف : مجموعه ای از گره ها که هرگره حداقل شامل يک فيلد داده ويک فيلد اشاره گر است. اشاره گر هر گره از نوع خود گره است. هر گره به وسيله ی اشاره گر خود به گره بعدی اشاره می کند. B. Z. A. 0. نقا يص کار با آرا يه ها به صورت ترت يب ی.
E N D
تعريف ليست پيوندي Link List • تعريف : مجموعه ای از گره ها که هرگره حداقل شامل يک فيلد داده ويک فيلد اشاره گر است. • اشاره گر هر گره از نوع خود گره است. • هر گره به وسيله ی اشاره گر خود به گره بعدی اشاره می کند. . . . B Z A 0
نقايصکار با آرايه ها به صورت ترتيبی • بازگشت ناپذير بودن حافظه بعد از گرفتن آن • لازم بودن پيش بينی بيشترين حافظه مورد نياز • پر هزينه بودن اضافه کردن عنصر • پر هزينه بودن حذف کردن عنصر
پر هزينه بودن اضافه کردن عنصر • می خواهيم C را به آن اضافه کنيم به طوری که ترتيب آن الفبايی بماند. 0 1 2 3 4 5 Shift
پر هزينه بودن اضافه کردن عنصر-ادامه 0 1 2 3 4 5 • سوال:مرتبه الگوريتم بالا چيست؟ O(n)
پر هزينه بودن حذف کردن عنصر • اگر بخواهيم B را از آرايه ی قبلی حذف کنيم بايد تمام عناصر بعد از آن را يکی به عقب بياوريم 0 1 2 3 4 5 shift • مرتبه اين الگوریتم نيز (n)O است.
راه حل مشکلات ناشی از کار با آرايه به صورت ترتيبی • استفاده ازليست پيوندی مزايا: • مجبور نيستيم داده ها را در فواصل مشخصی ازهم قرار دهيم. • می توان حافظه ی بدون استفاده را به کامپيوتربرگرداند.
- عمليات ليست پيوندي - ايجاد ليست - درج گره در ليست - حذف گره از ليست - جستجو در ليست - مرتب سازي ليست - معكوس كردن ليست - و ...
ساختمان داده مورد نياز • جهت پياده سازي لينك ليست: • استفاده از آرايه • استفاده از اشاره گر Pointer
پياده سازي ليست پيوندی به وسيله ی آرايه • برای ايجاد اين ليست بايد از دو آرايه استفاده کرد. • آرايه ی اول برای داده ها : اين آرايه از نوع داده ی مورد نظر انتخاب می شود (مثلا يک structure) • آرايه ی دوم برای اتصال ها : اين آرايه که از نوع int است.متناظر با داده هاست.که نشان دهنده ی آدرس داده بعدی است.
A B C I H K 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] B I C A H K Data First = 4 Link 3 5 1 0 8 -1 پياده سازي ليست پيوندی به وسيله ی آرايه-ادامه
A B C I H K [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] B I C A H K Data First = 4 3 5 1 0 8 -1 Link درج در ليست پيوندی 0
I C K A B H 0 D [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] Data B I D C A H K First = 4 Link 3 5 1 0 8 -1 درج در ليست پيوندی-ادامه
A B C I H K 0 D [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] Data B I D C A H K First = 4 Link 3 5 1 1 0 8 -1 درج در ليست پيوندی-ادامه
A B C I H K 0 D [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] Data B I D C A H K First = 4 Link 3 5 1 2 0 8 -1 درج در ليست پيوندی-ادامه
A B C D I H K 0 [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] Data B I D C A H K First = 4 Link 3 5 1 2 0 8 -1 درج در ليست پيوندی-ادامه
مراحل درج در ليست پيوندی • 1)قرار دادن داده ی لينک در آرايه ی داده ها • 2)اشاره دادن عضو جديد به عضو بعد از خودش • 3)اشاره دادن عضو قبل از عضو جديد به عضو جديد • نکته : هميشه ابتدا عضوجديد را در ليست قرار می دهيم سپس عضوهايی را که بايد به عضو جديد اشاره کنند به آن اشاره می دهيم.
پياده سازي با اشاره گر • تعريف يك نود • لازم است اين مسئله مشخص شود که فيلدهای ما چه نوع داده ای هستند.(به عنوان مثال می توان يک کاراکتر) class CharNode { private: char data; CharNode *link; };
روش های طراحی ليست • طرح اول: • متغير first را از نوع به عنوان متغير سراسری در نظر می گيريم. Node *first; • اشاره گر link و کاراکتر data اعضای private هستند. • خطاي زمان اجرا
روش های طراحی ليست طرح دوم: • data , link را به صورت public در بياوریم. (نقض اصل محصور سازي) • از توابع set و get برای هر کدام استفاده نماييم.(نقض اصل مخفي سازي)
طراحی ليست به وسيله ی کلاس مدير • اصل مخفی سازی داده ها • دسترسي ساده تر به اطلاعات يک کلاس دیگر تعريف می شود که حاوی کل ليست باشد (first).
طراحی ليست به وسيله ی کلاس مدير-ادامه class List { public: //list manipulation operations private: Node * first; }; class Node { friend class List; private : char data; Node * link; };
Node . . . 0 first A B N List رابطه ی مفهومی بين کلاس ليست و کلاس نود Node ... 0 first A B N List رابطه ی واقعی بين کلاس ليست و کلاس نود رابطه ی بين کلاس مدير (List) و کلاس گره (Node)
دستکاری اشاره گرها در C++ • تعريف يک اشاره گر: Node * pointer; • گرفتن حافظه برای اشاره گر: pointer = new Node; • آزاد کردن حافظه : delete pointer;
B C first مثال – ايجاد ليست با دو گره void List::Create2() { first = new Node (‘B’); first link = new Node (‘C’); } Node :: Node (char element =0) { data = element; link = 0 ; //null pointer }
A A B C first A B C first مثال – درج گره در ابتداي ليست void List :: InsertFirst () { Node *t = new Node(‘A’); t link = first; first = t; }
يک کلاس ليست پيوندی با قابليت استفاده مجدد • بهتر نيست که يک بار يک ليست را طراحی کنيم و چندين بار از آن استفاده کنيم؟ • برای اين که بتوانيم از يک ليست پيوندی برای چند بار استفاده کنيم بايد از کلاس های الگو(template) استفاده کنيم.
تعريف ليست های با قابليت استفاده ی مجدد template <class Type> class List; //forward declaration template <class Type> class ListNode { friendclass List<Type>; private : Type date; ListNode *link; }; template <class Type> class List { public : List(){first = 0;} private: ListNode <Type> *first; };
عملکردها روی ليست پيوندی • 1) نمايش ليست پيوندی • 2) اضافه کردن عنصری در ليست • 3) حذف کردن عنصر • و ...
نمایش ليست پيوندی(پيمايش) Output : A temp first ِA ِB C ِD
Output : A B temp first ِA ِB C ِD temp first ِA ِB C ِD نمايش ليست پيوندی(پيمايش)-ادامه
Output : A B C temp first ِA ِB C ِD temp first ِA ِB C ِD temp first ِA ِB C ِD نمايش ليست پيوندی(پيمايش)-ادامه
Output : A B C D temp first ِA ِB C ِD temp first ِA ِB C ِD temp first ِA ِB C ِD temp first ِA ِB C ِD نمايش ليست پيوندی(پيمايش)-ادامه
نمايش ليستپيوندی)پيمايش(-ادامه void ListNode :: Print() { if( !first ) return; //no node Node *temp = first; while(temp) //traverse list { cout << temp data; temp = temp link; //next node } }
اضافه کردن عنصر جديد • البته برای کاربردهای مختلف اضافه کردن فرق می کند. • ما در اينجا اضافه کردن عنصر جديد بعد از يک عنصر مشخص را نشان می دهيم. • مراحل کار: 1) نصب عنصر جديد 2) تنظيم اشاره گرهای مربوط به عنصر جديد
اضافه کردن عنصر جديد curNode first 0 newNode 0
اضافه کردن عنصر جديد-ادامه curNode first 0 A B D E newNode C newNode link = curNode link ;
اضافه کردن عنصر جديد-ادامه curNode first 0 A B D E newNode C curNode link = newNode ;
اضافه کردن عنصر جديد-ادامه curNode first A B C D E 0 newNode
اضافه کردن عنصر جديد-ادامه template <class Type> void ListNode<Type> :: Insert (Node*curNode ,Node *newNode) { newNode --> link = curNode --> link ; //assign newNode curNode --> link = newNode ; //assign curNode }
اضافه کردن به ابتدای ليست • بدين دليل اين حالت خاص را بررسی می کنیم که بعد از اضافه کردن عنصر بايد اشاره گر first به ابتدای ليست اشاره کند. • مراحل کار 1) نصب عنصر جديد 2) اشاره دادن اشاره گر first به عنصر جديد
newNode 0 A first 0 B C D E اضافه کردن به ابتدای ليست
اضافه کردن به ابتدای ليست-ادامه newNode A first 0 B C D E newNode link = first;
newNode A first 0 B C D E اضافه کردن به ابتدای ليست-ادامه first = newNode;
newNode first 0 A B C D E اضافه کردن به ابتدای ليست-ادامه
اضافه کردن به ابتدای ليست-ادامه template <class Type> void ListNode<Type> :: InsertFirst(Node *newNode) { if( !first ) //no node { first = newNode; newNode --> link = NULL; return; } newNode --> link = first; //assign newNode first = newNode; }
حذف عنصر از ليست پيوندی • مراحل کار: 1) تنظيم اشاره گرها 2) حذف کردن گره (آزاد کردن حافظه)
حذف عنصر از ابتدای ليست پيوندی curNode first ِA ِB C ِD ِE 0
حذف عنصر از ليست پيوندی-ادامه curNode first ِA ِB C ِD ِE 0 first = first link;
first ِB C ِD ِE 0 حذف عنصر از ابتدای ليست پيوندی-ادامه delete cur;