You are on page 1of 86

‫ألقوائم ألمتصلة‬

‫‪LINKED LISTS‬‬

‫تعريف‬ ‫‪.١‬‬
‫تمثيل ألقوائم ألمتصلة‬ ‫‪.٢‬‬
‫إنشاء قائمة متصلة مفردة‬ ‫‪.٣‬‬
‫إدخال ألبيانات‬ ‫‪.٤‬‬
‫التجول في قائمة متصلة مفردة‬ ‫‪.٥‬‬
‫ألعمليات أالساسية على ألقائمة ألمتصلة ألمفردة‬ ‫‪.٦‬‬
‫ألبرنامج ألعام‬ ‫‪.٧‬‬
‫ألقا ئمة ألمتصلة ألمفردة ألدورانية‬ ‫‪.٨‬‬
‫ألعمليات أالساسية على ألقائمة ألمتصلة ألدورانية‬ ‫‪.٩‬‬
‫ألبرنامج ألعام‬ ‫‪.١٠‬‬
‫ألقا ئمة ألمتصلة ألمزدوجة‬ ‫‪.١١‬‬
‫إنشاء قائمة متصلة مزدوجة‬ ‫‪.١٢‬‬
‫إدخال ألبيانات‬ ‫‪.١٣‬‬
‫ألتجول في قائمة متصلة مزدوجة‬ ‫‪.١٤‬‬
‫ألعمليات أالساسية على ألقائمة ألمتصلة ألمزدوجة‬ ‫‪.١٥‬‬
‫ألبرنامج ألعام‬ ‫‪.١٦‬‬
‫ألقا ئمة ألمتصلة ألمزدوجة ألدورانية‬ ‫‪.١٧‬‬
‫إدخال ألبيانات‬ ‫‪.١٨‬‬
‫ألتجول في قائمة متصلة مزدوجة دورانية‬ ‫‪.١٩‬‬
‫تمارين‬ ‫‪.٢٠‬‬
‫‪Definition‬‬ ‫‪ .١‬تعريف‬

‫ألقوائم ألمتصلة ھي تركيب من ألبيانات كل عنصر )‪ (item‬فيھا يسمى عقدة )‪ .(node‬كل عقدة‬
‫تحتوي على حقلين إثنين ‪:‬‬

‫‪ -‬حقل ألبيانات ‪ : Data field‬وذلك لخزن ألبيانات ذات ألعالقة ‪.‬‬


‫‪ -‬حقل ألمؤشر ‪ : Pointer field‬وذلك لخزن ألعنوان )‪ ( address‬للعقدة ألتالية‬
‫في ألقائمة ويسمى إتصال )‪.(link‬‬

‫ألمخطط ألتالي يمثل ألعقدة ومكوناتھا ‪:‬‬

‫‪link‬‬

‫‪Data‬‬ ‫إتصال مع ألعقدة ألتالية‬

‫ألشكل ‪ ١ -١‬عقدة وھي ألعنصر ألمھم في ألقائمة ألمتصلة‬

‫ألمؤشر ألذي يؤش‪:‬ر عل‪:‬ى ألعق‪:‬دة أالول‪:‬ى يخ‪:‬زن ف‪:‬ي موق‪:‬ع منفص‪:‬ل‪ ،‬يس‪:‬مى أل‪:‬رأس )‪ ، (head‬ف‪:‬ي‬
‫حين ألعقدة أالخي‪:‬رة‪ ،‬تس‪:‬مى أالخي‪:‬ر )‪ (last‬تؤش‪:‬ر عل‪:‬ى ف‪:‬راغ )‪ .(NULL‬ألش‪:‬كل ‪ ٢ -١‬يوض‪:‬ح‬
‫ذلك‪:‬‬

‫‪head‬‬ ‫‪last‬‬

‫‪Data1‬‬ ‫‪Data2‬‬

‫ألشكل ‪ ٢ -١‬قائمة متصلة تتكون من عقدتين‬

‫‪Representation of the linked list‬‬ ‫‪ .٢‬تمثيل ألقوائم ألمتصلة‬


‫ھنالك إسلوبين إثنين لتمثيل ألقوائم ألمتصلة في ألذاكرة ) ‪: (memory‬‬

‫‪ -‬ألتمثيل ألساكن )‪ (static‬بإستخدام ألصفوف‬


‫‪ -‬ألتمثيل ألديناميكي )‪ (dynamic‬بإستخدام ألتخزين ألحر‬

‫ألتمثيل ألساكن يمكن إعتباره مصفوفتين إثنين ‪ :‬أالولى للبيانات وأالخرى لالتصال‪ .‬ھذا ما‬
‫نالحظه في ألشكل ‪ ٣ -١‬وكما يلي ‪:‬‬
‫ألبيانات‬

‫‪14‬‬ ‫‪23‬‬ ‫‪35‬‬ ‫‪38‬‬ ‫‪40‬‬ ‫‪50‬‬ ‫‪88‬‬ ‫‪. . .‬‬

‫أالتصال‬

‫‪30‬‬ ‫‪49‬‬ ‫‪41‬‬ ‫‪X‬‬ ‫‪55‬‬ ‫‪42‬‬ ‫‪. . .‬‬

‫ألشكل ‪ ٣ -١‬ألتمثيل ألساكن وألمتمثل بمصفوفتين‬

‫إن ھذا ألتمثيل ھو عبارة عن صفين متوازيين لھما نفس ألحجم )‪ (size‬لتخزين كامل للقوائم‬
‫ألمتصلة‪.‬‬

‫من ألناحية أالخرى‪ ،‬فأن ألطريقة ألكفؤة في تمثيل ألقوائم ألمتصلة ھي ألطريقة ألدينامكية‪ .‬ففي‬
‫ھذه ألطريقة يتكون بنك ألذاكرة ) مجموعة من ألفراغات ألحرة للذاكرة (‪ ،‬وقائد )‪(program‬‬
‫للذاكرة‪ .‬خالل إنشاء ألقوائم ألمتصلة‪ ،‬يخصص موقع لكل عقدة في ألذاكرة ويعمل ألقائد في‬
‫ألبحث عن عنوان )‪ (address‬ذلك ألموقع‪.‬‬

‫إن ألقائد سوف تكون مھمته ھي إدارة ألذاكرة ألديناميكية‪.‬‬

‫لكي نتعامل مع ألقوائم ألمتصلة‪ ،‬يجب علينا مراعات ألضوابط أالتية‪:‬‬

‫‪head of the linked list‬‬ ‫رأس ألقائمة‬ ‫‬


‫‪number of items‬‬ ‫عدد ألعناصر‬ ‫‬
‫‪data for each item‬‬ ‫ألبيان لكل عنصر‬ ‫‬
‫‪the last node‬‬ ‫ألعقدة أالخيرة‬ ‫‬

‫ألشكل ألتالي ) ألشكل ‪ ( ٤ -١‬يبين لنا قائمة متصلة مع مجموعة ألضوابط‬

‫‪head‬‬ ‫‪last‬‬
‫‪Data1‬‬ ‫‪Data2‬‬ ‫‪Data3‬‬ ‫‪Data4‬‬ ‫‪Data5‬‬
‫‪*head‬‬ ‫‪*last‬‬

‫ألشكل ‪ ٤ -١‬قائمة متصلة مع مجموعة ألضوابط‬

‫مالحظة‪:‬‬

‫إن كلمة ألرأس )‪ (head‬ھنا تمثل عنوان ألعقدة االولى في ألذاكرة فھي إذن مؤشر‬
‫)‪ (pointer‬يؤشر على ألعقدة أالولى في ألقائمة ألمتصلة‪.‬‬
‫وأن ألسھم )‪ (arrow‬في كل عقدة يمثل تأشير للعقدة ألتالية‪.‬‬

‫إن لكل عقدة في ألقائمة ألمتصلة مكونان )‪ (components‬رئيسيان وھذا ما ذكرناه عند‬
‫تعريف ألقائمة ألمتصلة ) حقل ألبيانات وحقل ألمؤشر ‪ ،‬أنظر ألشكل ‪ ( ١ -١‬وعليه فإن ألخطوة‬
‫ألمھمة النشاء ألعقدة برمجيا ھي تعريف تركيب )‪ (struct‬وتكون صيغته على ألنحو ألتالي‪:‬‬

‫{ ‪struct nod‬‬
‫; ‪int Data‬‬
‫; ‪nod *link‬‬
‫;}‬

‫لكي نطبق ھذا ألتركيب‪ ،‬علينا أالعالن عن ألمؤشرات أالتية‪:‬‬

‫ ألرأس )‪ (head‬وألذي يؤشر على ألعقدة أالولى من ألقائمة ألمتصلة‬


‫ ألتيار )‪ (cur‬يمكن أن يؤشر على أية عقدة بما فيھا عقدة ألرأس‬
‫ أالخير )‪ (last‬ألمؤشر للعقدة أالخيرة‬

‫إن ألمتغيرات ألمناظرة لھا ھي‪:‬‬

‫ ‪*head‬‬
‫ ‪*cur‬‬
‫ ‪*last‬‬

‫وعلى ألترتيب‪.‬‬

‫ألصيغة ألبرمجية لالعالن عن ألمتغيرات ألثالثة يمكن صياغتھا وعلى ألنحو أالتي‪:‬‬

‫; ‪nod *head, *cur, *last‬‬


‫وتأتي ھذه ألعبارة بعد تعريف ألتركيب )‪.(struct‬‬

‫‪Creating a Single linked List‬‬ ‫‪ .٣‬إنشاء قائمة متصلة مفردة‬

‫إن ألفكرة ألرئيسية في إنشاء قائمة متصلة مفردة تكمن في حساب قيم ألمؤشرات ألرأس ‪ ،‬ألتيار‬
‫وأالخير‪ .‬يمكن تنفيذ ذلك وذلك بإستخدام ألمؤثر جديد )‪ (new‬وألذي بدوره يوفر موقع تخزين‬
‫ديناميكي‪.‬‬

‫وعليه‪ ،‬النشاء قائمة متصلة مفردة نتبع ألخطوات ألبرمجية أالتية‪:‬‬

‫‪// Program Chr1_01.cpp‬‬


‫>‪# include<iostream.h‬‬

‫{ ‪struct nod‬‬
‫; ‪int Data‬‬
‫; ‪nod *link‬‬
‫;}‬
‫; ‪nod *head, *cur, *last‬‬

‫) ( ‪void create‬‬
‫{‬
‫; ‪head = new nod‬‬
‫; ‪cur = head‬‬
‫) ‪for (int i = 1 ; i <= 4 ; i++‬‬
‫{‬
‫; ‪cur -> link = new nod‬‬
‫; ‪cur = cur -> link‬‬
‫}‬
‫; ‪last = cur‬‬
‫; ‪last -> link = NULL‬‬
‫}‬

‫) (‪main‬‬
‫} ; ) ( ‪{ create‬‬

‫في ھذا ألبرنامج تم إنشاء قائمة متصلة مفردة متكونة من خمسة عقد ويمكن توضيح ذلك‪:‬‬

‫ألعبارة‬

‫; ‪head = new nod‬‬

‫من أجل إنشاء عقدة ألرأس وألتي يمكن تمثيلھا بألشكل ‪٥ -١‬‬

‫‪head‬‬

‫‪*head‬‬

‫ألشكل ‪ ٥ -١‬عقدة ألرأس‬

‫أما ألعبارة‬

‫; ‪cur = head‬‬

‫فھي تعمل على نسخ ألعقدة ألرأس إلى ألعقدة ألتيار‪ ،‬يمكن توضيح ذلك بالشكل ‪٦ -١‬‬
‫‪head‬‬ ‫‪cur‬‬

‫‪*head, *cur‬‬

‫ألشكل ‪ 6 -١‬نسخ عقدة ألرأس‬

‫أما جملة ألتكرار ‪ for‬فھي تعمل على إنشاء بقية ألعقد حيث أن ألعبارة‪:‬‬

‫; ‪cur -> link = new nod‬‬

‫تعمل على إنشاء عقدة تلي ألعقدة ألتيار‪ ،‬أما ألعبارة‪:‬‬

‫; ‪cur = cur -> link‬‬

‫فھي لنقل أالسم تيار )‪ (cur‬إلى ألعقدة ألتالية وألتي تم إنشاؤھا وكما ھو موضح بألشكل ‪٧ -١‬‬

‫‪head‬‬ ‫‪cur‬‬

‫‪*head‬‬ ‫‪*cur‬‬

‫ألشكل ‪ ٧ -١‬نقل أالسم ‪ cur‬إلى ألعقدة ألتالية‬

‫بعد سلسلة من ألتكرارات نحصل على ألقائمة ألمتصلة ألمفردة‪ ،‬كما ھو موضح في ألشكل ‪٨ -١‬‬

‫‪head‬‬ ‫‪cur‬‬

‫‪*head‬‬ ‫‪*cur‬‬

‫ألشكل ‪ ٨ -١‬قائمة متصلة مفردة‬


‫من ألناحية أالخرى فإن ألبرنامج سوف يمنح ألعقدة أالخيرة إسم أالخير )‪ (last‬وألجملة ألخاصة‬
‫بذلك ھي‪:‬‬

‫; ‪last = cur‬‬

‫وبما أن ألعقدة أالخيرة تؤشر على فراغ )‪ (NULL‬فإن ألجملة ألخاصة بذلك ھي‪:‬‬
‫; ‪last -> link = NULL‬‬

‫إن ألصيغة ألنھائية للقائمة ألمتصلة ألمفردة تكون كما في ألشكل ‪٩ -١‬‬

‫‪head‬‬ ‫‪last‬‬

‫‪*head‬‬ ‫‪*last‬‬
‫ألشكل ‪ ٩ -١‬قائمة متصلة مفردة‬

‫‪Inserting data‬‬ ‫‪ .٤‬إدخال ألبيانات‬

‫ھنا نوضح كيفية إدخال ألبيانات لكل عقدة من ألعقد‪ ،‬لقد تم تخص‪:‬يص دال‪:‬ة )‪ (function‬لق‪:‬راءة‬
‫ألبيانات من لوحة ألمفاتيح ثم وضع كل قيمة في ألعقدة ألمناسبة‪.‬‬
‫ألدالة ستكون على ألنحو أالتي‪:‬‬

‫) ( ‪void read‬‬
‫{‬
‫; " ‪cout<< "Enter the value for the head :‬‬
‫; ‪cin>> head -> Data‬‬
‫; ‪cur = head‬‬
‫)‪while( cur->link‬‬
‫{‬
‫; " ‪cout<< " Enter the values of the items :‬‬
‫; ‪cur = cur -> link‬‬
‫; ‪cin>> cur -> Data‬‬
‫}‬
‫}‬

‫تضمن ألبرنامج أعاله قراءة‪ ،‬من لوحة ألمفاتيح‪ ،‬ألقيمة ألخاصة بألرأس وذلك بإستخدام ألعبارة‬

‫; ‪cin>> head -> Data‬‬

‫كما تم إستخدام ألعبارة‬


‫)‪while( cur->link‬‬

‫وذلك للمرور بكافة ألعقد وتخصيص ألقيمة ألبيانية لتلك ألعقد‪ .‬سوف ينتھي تأثير ألصيغة‬
‫ألتكرارية عندما يتحقق ألشرط‪:‬‬

‫‪cur -> link == NULL‬‬


‫عند إضافة ھذه ألدالة للبرنامج ‪ Chr1_01‬فإن صيغة ألتنفيذ ستكون كما يلي‪:‬‬

‫) (‪main‬‬
‫{‬
‫; ) ( ‪create‬‬
‫; ) ( ‪read‬‬
‫}‬

‫يطلب منا ألبرنامج إدخال قيم لكل من‪:‬‬

‫ ألرإس‬
‫ أربعة عقد متبقية تشمل كذلك أالخير‬

‫مثال ذلك عند إدخال ألقيم‪:‬‬

‫ ‪١‬‬
‫ ‪٩ ،٦ ،٥ ،٢‬‬

‫فإن ألقائمة ألمتصلة ستأخذ ألشكل ‪ ١٠ -١‬وكما ياي‪:‬‬

‫‪head‬‬ ‫‪last‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪٦‬‬ ‫‪9‬‬


‫‪1‬‬
‫‪*head‬‬ ‫‪*last‬‬
‫ألشكل ‪ ١٠ -١‬قائمة متصلة مفردة‬

‫‪Traversing a Single Linked List‬‬ ‫‪ .٥‬التجول في قائمة متصلة مفردة‬

‫نعني بألتجول في قائمة متصلة ھو زيارة كل عق‪:‬دة م‪:‬ن عق‪:‬د ألقائم‪:‬ة مبت‪:‬دئين ب‪:‬ألرأس حت‪:‬ى ألعق‪:‬دة‬
‫أالخيرة‪ .‬ألتركيب ألخاص للدالة يكون على ألنحو أالتي‪:‬‬

‫) (‪void write‬‬
‫{‬
‫;‪int l = 0‬‬
‫; ‪cur = head‬‬
‫)‪while (cur‬‬
‫{‬
‫" = ] "<<‪cout<< "Data of node [ " <<l++‬‬
‫;‪<<cur->Data<<endl‬‬
‫;‪cur = cur -> link‬‬
‫}‬
‫}‬
‫إضافة ألدالة إلى ألبرنامج ألسابق مع إجراء أالضافة ألى ألصيغة ألتنفيذية وكما يلي‪:‬‬

‫) ( ‪main‬‬
‫{‬
‫; ) ( ‪create‬‬
‫; ) ( ‪read‬‬
‫; ) ( ‪clrscr‬‬
‫; ) ( ‪write‬‬
‫}‬

‫عند ألتنفيذ‪ ،‬نحصل على ألنتائج أالتية‪:‬‬

‫= ] ‪Data of node [ 0‬‬ ‫‪1‬‬


‫= ] ‪Data of node [ 1‬‬ ‫‪2‬‬
‫= ] ‪Data of node [ 2‬‬ ‫‪5‬‬
‫= ] ‪Data of node [ 3‬‬ ‫‪6‬‬
‫= ] ‪Data of node [ 4‬‬ ‫‪9‬‬

‫مالحظة‪:‬‬
‫تم إستخدام ألدالة ‪ clrscr‬وذلك الزالة ألنص من ألنافذة ووضع ألمؤشر عند ألبداية‪.‬‬
‫بكل تأكيد سوف نضمن برنامجنا بألملف ألرأسي ‪ conio.h‬ألذي يحوي ألدالة ‪. clrscr‬‬

‫‪ .٦‬ألعمليات أالساسية على ألقائمة ألمتصلة ألمفردة‬


‫‪Basic Operations on Single Linked List‬‬

‫يتضمن ھذا ألجزء من ألفصل ألمواضيع أالتية‪:‬‬

‫ حشر ‪ insert‬عقدة في موقع معين من ألقائمة ألمتصلة‬


‫ حذف ‪ delete‬عقدة من موقع معين في ألقائمة ألمتصلة‬
‫ إبتداء وتدمير ألقائمة ألمتصلة‬
‫حشر عقدة‪:‬‬
‫لحشر عقدة جديدة في بداية ألقائمة ألمتصلة ألمفردة نستخدم ألدالة أالتية‪:‬‬

‫)‪void adfirst(int m‬‬


‫{‬
‫) ‪if( !head‬‬
‫{‬
‫;‪head = new nod‬‬
‫;‪head->Data = m‬‬
‫;‪last = head‬‬
‫;‪last -> link = NULL‬‬
‫}‬
‫‪else‬‬
‫{‬
‫;‪nod *temp = new nod‬‬
‫;‪temp -> Data = m‬‬
‫;‪temp -> link =head‬‬
‫;‪head = temp‬‬
‫}‬
‫}‬

‫يفترض ألجزء أالول م‪:‬ن ألدال‪:‬ة ع‪:‬دم إحت‪:‬واء ألقائم‪:‬ة ألمتص‪:‬لة ألمف‪:‬ردة عل‪:‬ى أي‪:‬ة عق‪:‬دة وعلي‪:‬ه ف‪:‬إن‬
‫ألعقدة ألجديدة ستكون ھي ألعقدة ألرأس وھي ألعقدة أالخيرة في نفس ألوقت‪ .‬في ح‪:‬ين إن ل‪:‬م تك‪:‬ن‬
‫ألقائمة ألمتصلة ألمفردة خالية فإننا نستطيع إضافة ألعقدة ألجديدة في ألموقع ألمناسب‪.‬‬
‫ألشكل ‪ ١١ -١‬يوضح ألعبارتين من أالمر ‪ else‬وھي‪:‬‬

‫;‪nod *temp = new nod‬‬


‫;‪temp -> Data = m‬‬

‫‪head‬‬ ‫‪last‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪6‬‬ ‫‪9‬‬

‫‪temp‬‬

‫‪m‬‬

‫‪*temp‬‬
‫ألشكل ‪ ١١ -١‬إضافة عقدة جديدة لقائمة متصلة مفردة‬

‫أما ألعبارتين أالخيرتين‪:‬‬

‫;‪temp -> link =head‬‬


‫;‪head = temp‬‬

‫فھي تعمل على ربط ألعقدة ألجديدة بألعقدة ألرأس ثم يتم إطالق إسم ألرأس على ألعقدة ألجديدة‪.‬‬
‫ألشكل ‪ ١٢ -١‬يوضح ذلك‬
‫‪last‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪6‬‬ ‫‪9‬‬

‫‪head‬‬

‫‪m‬‬

‫ألشكل‪ ١٢ -١‬ألقائمة ألمتصلة ألمفردة بعد أالضافة‬

‫يمكن إضافة ھذه ألدالة ليكون ألجزء ألتنفيذي للبرنامج على ألنحو أالتي‪:‬‬

‫) (‪main‬‬
‫; ) ( ‪{ create‬‬
‫;) ( ‪read‬‬
‫;) ( ‪clrscr‬‬
‫;) ( ‪write‬‬
‫;"‪cout<<" Enter the Data for the new first node :‬‬
‫;‪cin>>m‬‬
‫;)‪adfirst(m‬‬
‫;) ( ‪clrscr‬‬
‫} ;) ( ‪write‬‬

‫فإذا كانت قيمة ألبيانات للعقدة ألجديدة ھي ‪ m = 0‬فإن مخرجات ألبرنامج تكون على ألنحو‬
‫أالتي‪:‬‬

‫‪Data of node [ 0 ] = 0‬‬


‫‪Data of node [ 1 ] = 1‬‬
‫‪Data of node [ 2 ] = 2‬‬
‫‪Data of node [ 3 ] = 5‬‬
‫‪Data of node [ 4 ] = 6‬‬
‫‪Data of node [ 5 ] = 9‬‬

‫أما عند إضافة عقدة جديدة في نھاية ألقائمة ألمتصلة ألمفردة فيمكن تطبيق ألدالة أالتية‪:‬‬

‫)‪void adend(int n‬‬


‫{‬
‫) ‪if( !head‬‬
‫{‬
‫;‪head = new nod‬‬
‫;‪head->Data = n‬‬
‫;‪head -> link = NULL‬‬
‫;‪last = head‬‬
‫}‬
‫‪else‬‬
‫{‬
‫;‪nod *temp = new nod‬‬
‫;‪temp -> Data = n‬‬
‫;‪last -> link = temp‬‬
‫;‪last = temp‬‬
‫; ‪last -> link = NULL‬‬
‫}‬
‫}‬

‫وكم‪::‬ا ذكرن‪::‬ا س‪::‬ابقا وب‪::‬إفتراض ب‪::‬أن ألج‪::‬زء أالول م‪::‬ن ألدال‪::‬ة يتعام‪::‬ل م‪::‬ع قائم‪::‬ة متص‪::‬لة مف‪::‬ردة ال‬
‫تحتوي على أية عقدة وعليه فإن ألعقدة ألجديدة ستكون ھي ألعق‪:‬دةأالخيرة وھ‪:‬ي ألعق‪:‬دة أل‪:‬رأس ف‪:‬ي‬
‫نف‪::‬س ألوق‪::‬ت‪ .‬ف‪::‬ي ح‪::‬ين إن ل‪::‬م تك‪::‬ن ألقائم‪::‬ة ألمتص‪::‬لة ألمف‪::‬ردة خالي‪::‬ة فإنن‪::‬ا نس‪::‬تطيع إض‪::‬افة ألعق‪::‬دة‬
‫ألجديدة‪.‬‬
‫ألشكل ‪ ١٣ -١‬يوضح ألعبارتين من أالمر ‪ else‬وھي‪:‬‬

‫;‪nod *temp = new nod‬‬


‫;‪temp -> Data = n‬‬

‫‪head‬‬ ‫‪last‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪6‬‬ ‫‪9‬‬

‫‪temp‬‬

‫‪n‬‬
‫‪*temp‬‬
‫ألشكل ‪ ١٣-١‬إضافة عقدة جديدة لقائمة متصلة مفردة‬

‫أما ألعبارات أالخيره‪:‬‬

‫;‪last-> link = temp‬‬


‫;‪last = temp‬‬
‫;‪last -> link = NULL‬‬
‫فھي تعمل على ربط ألعقدة أالخيرة بألعقدة ألجديدة ث‪:‬م ي‪:‬تم إط‪:‬الق إس‪:‬م أالخيرعل‪:‬ى ألعق‪:‬دة ألجدي‪:‬دة‬
‫وألعبارة أالخيرة تجعل من مؤشر ألعقدة أالخيرة يؤشر على ألفراغ‪.‬‬
‫ألشكل ‪ ١٤ -١‬يوضح ذلك‬

‫‪head‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪6‬‬ ‫‪9‬‬

‫‪last‬‬

‫‪n‬‬

‫ألشكل ‪ ١٤ -١‬ألقائمة ألمتصلة ألمفردة ألجديدة‬

‫يمكن إضافة ھذه ألدالة ليكون ألجزء ألتنفيذي للبرنامج على ألنحو أالتي‪:‬‬

‫) (‪main‬‬
‫; ) ( ‪{ create‬‬
‫;) ( ‪read‬‬
‫;) ( ‪clrscr‬‬
‫;) ( ‪write‬‬
‫;"‪cout<<" Enter the Data for the new end node :‬‬
‫;‪cin>>n‬‬
‫;)‪adend(n‬‬
‫;) ( ‪clrscr‬‬
‫} ;) ( ‪write‬‬

‫فإذا كانت قيمة ألبيانات للعقدة ألجديدة ھي ‪ n = 10‬فإن مخرجات ألبرنامج ستكون على ألنحو‬
‫أالتي‪:‬‬
‫‪Data of node [ 0 ] = 1‬‬
‫‪Data of node [ 1 ] = 2‬‬
‫‪Data of node [ 2 ] = 5‬‬
‫‪Data of node [ 3 ] = 6‬‬
‫‪Data of node [ 4 ] = 9‬‬
‫‪Data of node [ 5 ] = 10‬‬

‫أما عند إضافة عقدة جديدة في مكان ما من ألقائمة ألمتصلة ألمفردة فيمكن تطبيق ألدالة أالتية‪:‬‬

‫)‪void adany (int me‬‬


‫{‬
‫; ‪nod *temp, *ptr‬‬
‫; ‪temp = new nod‬‬
‫; ‪temp -> Data = me‬‬
‫; ‪cur = head‬‬
‫) ‪while (cur -> Data < me‬‬
‫{‬
‫; ‪ptr = cur‬‬
‫; ‪cur = cur -> link‬‬
‫}‬
‫;‪ptr ->link=temp‬‬
‫; ‪temp->link = cur‬‬
‫}‬

‫ألدالة أعاله تعمل على تحديد موقع ألعقدة ألجديدة وذلك بمعرفة ألعقدة ألتي قبلھا ‪ ptr‬وألعقدة‬
‫ألتي بعدھا ‪ ، cur‬ويتم تحديد ذلك بإستخدام ألصيغة ‪ while‬حيث تحدد قيمة ألعقدة ألسابقة‬
‫بألعبارة‬

‫; ‪ptr = cur‬‬

‫وتحدد ألقيمة ألتالية بألعبارة‬

‫; ‪cur = cur -> link‬‬

‫مالحظة‪:‬‬
‫ألدالة أعاله صحيحة عندما تكون ألبيانات مرتبة ترتيبا تصاعديا‪.‬‬

‫ألشكل ‪ ١٥ -١‬يوضح إنشاء ألعقدة ألجديدة ) ‪(*temp‬‬

‫‪head‬‬ ‫‪last‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪6‬‬ ‫‪9‬‬

‫‪temp‬‬
‫‪me‬‬

‫ألشكل ‪ ١٥ -١‬إضافة عقدة جديدة إلى ألقائمة ألمتصلة ألمفردة‬


‫أما ألشكل ألتالي ) ألشكل ‪ ( ١٦ -١‬يوضح لنا عمل ألعبارة‬
‫; ‪cur = head‬‬

‫‪head‬‬ ‫‪cur‬‬ ‫‪last‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪6‬‬ ‫‪9‬‬

‫‪temp‬‬

‫‪me‬‬

‫ألشكل ‪١٦ -١‬وضع ألمؤشر ‪ cur‬عند رأس ألقائمة ألمتصلة ألمفردة‬

‫يتم تحديد ألعقدة ألسابقة وألالحقة للعقدة ألمضافة وكما ھو في بألشكل آالتي ) ألشكل ‪( ١٧ -١‬‬

‫‪head‬‬ ‫‪ptr‬‬ ‫‪cur‬‬ ‫‪last‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪6‬‬ ‫‪9‬‬

‫‪temp‬‬

‫‪me‬‬

‫ألشكل ‪ ١٧ -١‬تحديد ألعقدتين ألسابقة وألالحقة للعقدة ألجديدة‬

‫أما ألعبارتين ‪:‬‬

‫; ‪ptr -> link = temp‬‬


‫;‪temp -> link = cur‬‬

‫فھي ضرورية جدا وذلك الجراء عملية ربط ألعقدة ألجديدة )‪ (temp‬بألعقدتين ألسابقة )‪(ptr‬‬
‫وألعقدة أالحقة )‪.(cur‬‬

‫ألشكل ‪ ١٨ -١‬يوضح إجراء عملية ألربط‬


‫‪head‬‬ ‫‪ptr‬‬ ‫‪cur‬‬ ‫‪last‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪6‬‬ ‫‪9‬‬

‫‪temp‬‬

‫‪3‬‬

‫ألشكل ‪ ١٨ -١‬ألقائمة ألمتصلة ألمفردة ألجديدة‬

‫فإذا كانت قيمة ألبيانات للعقدة ألجديدة ھي ‪ me = 3‬فإن مخرجات ألبرنامج تكون على ألنحو‬
‫أالتي‪:‬‬

‫‪Data of node [ 0 ] = 1‬‬


‫‪Data of node [ 1 ] = 2‬‬
‫‪Data of node [ 2 ] = 3‬‬
‫‪Data of node [ 3 ] = 5‬‬
‫‪Data of node [ 4 ] = 6‬‬
‫‪Data of node [ 5 ] = 9‬‬

‫حذف عقدة‪:‬‬

‫إن عملية حذف عقدة من قائمة متصلة مفردة تشبه عملية إضافة عقدة جديدة إلى قائمة متصلة‬
‫مفردة‪ .‬إن ألحذف سيكون من ألماقع أالتية‪:‬‬

‫ بداية ألقائمة ألمتصلة ألمفردة‬


‫ أية موقع من ألقائمة ألمتصلة ألمفردة‬
‫ نھاية ألقائمة ألمتصلة ألمفردة‬

‫لحذف عقدة من بداية ألقائمة ألمتصلة ألمفردة نستخدم ألدالة أالتية‪:‬‬

‫) (‪void defirst‬‬
‫{‬
‫;‪cur = head‬‬
‫;‪head = head -> link‬‬
‫;‪delete cur‬‬
‫}‬
‫عند تطبيق ھذه ألدالة لحذف ألعقدة ألرأس من ألقائمة ألمتصلة ألمفردة فإن أولى ألخطوات ھي‬
‫تسمية ألعقدة ألرأس بألعقدة تيار )‪:(cur‬‬

‫; ‪cur = head‬‬

‫ألشكل ‪ ١٩ -١‬يوضح ذلك‪:‬‬

‫‪head‬‬ ‫‪cur‬‬ ‫‪last‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪6‬‬ ‫‪9‬‬

‫ألشكل ‪ ١٩ -١‬ألمؤشر ‪cur‬‬

‫أما ألعبارة‬
‫;‪head = head -> link‬‬

‫فتعمل على نقل ألمؤشر ‪ head‬إلى ألعقدة ألتالية وكما ھو موضح بألشكل ‪٢٠ -١‬‬

‫‪cur‬‬ ‫‪head‬‬ ‫‪last‬‬


‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪6‬‬ ‫‪9‬‬

‫ألشكل ‪ ٢٠ -١‬نقل ألمؤشر ‪head‬‬

‫وألخطوة أالخيرة تعمل على حذف ألعقدة ‪cur‬‬


‫;‪delete cur‬‬

‫ألصيغة ألنھائية للقائمة ألمتصلة ألمفردة ستكون على ألنحو أالتي‪:‬‬

‫‪head‬‬ ‫‪last‬‬
‫‪2‬‬ ‫‪5‬‬ ‫‪6‬‬ ‫‪9‬‬

‫ألشكل ‪ ٢١ -١‬ألقائمة ألمتصلة ألمفردة بعد ألحذف‬

‫وللحصول على ألبيانات يمكن تطبيق ألبرنامج أالتي‬


‫) (‪main‬‬
‫; ) (‪{ create‬‬
‫;) (‪read‬‬
‫;) (‪defirst‬‬
‫;) (‪clrscr‬‬
‫} ;) (‪write‬‬

‫مخرجات ألبرنامج تكون على ألنحو أالتي‪:‬‬

‫‪Data of node [ 0 ] = 2‬‬


‫‪Data of node [ 1 ] = 5‬‬
‫‪Data of node [ 2 ] = 6‬‬
‫‪Data of node [ 3 ] = 9‬‬

‫لحذف عقدة من نھاية ألقائمة ألمتصلة ألمفردة نستخدم ألدالة أالتية‪:‬‬

‫) (‪void delast‬‬
‫{‬
‫; ‪cur = head‬‬
‫) ‪while (cur -> link != last‬‬
‫;‪cur = cur -> link‬‬
‫;‪delete last‬‬
‫; ‪last = cur‬‬
‫;‪last -> link = NULL‬‬
‫}‬

‫فألعبارة أالولى‬
‫; ‪cur = head‬‬

‫تعمل على تسمية ألعقدة ألرأس بألعقدة ألتيار )‪ (cur‬وكما في ألشكل ‪٢١ -١‬‬

‫‪head‬‬ ‫‪cur‬‬ ‫‪last‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪6‬‬ ‫‪9‬‬

‫ألشكل ‪ ٢١ -١‬ألمؤشر ‪cur‬‬

‫وللوصول إلى ألعقدة ألتي تسبق ألعقدة أالخيرة نطبق ألصيغة أالتية‪:‬‬

‫) ‪while (cur -> link !=last‬‬


‫;‪cur = cur -> link‬‬
‫تتوقف جملة ‪ while‬عندما تؤشر ألعقدة ‪ cur‬على ألعقدة أالخيرة وكما في ألشكل ‪٢٢ -١‬‬

‫‪head‬‬ ‫‪cur‬‬ ‫‪last‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪6‬‬ ‫‪9‬‬

‫ألشكل ‪ ٢٢ -١‬ألوصول للعقدة قبل أالخيرة‬

‫نستطيع أالن وبسھولة تنفيذ ألجملة‪:‬‬


‫;‪delete last‬‬

‫وذلك لحذف ألعقدة أالخيرة‪.‬‬

‫ألشكل ‪ ٢٣ -١‬يبين ألقائمة ألمتصلة ألجديدة‬

‫‪head‬‬ ‫‪cur‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪6‬‬

‫ألشكل ‪ ٢٣ -١‬ألقائمة ألمتصلة ألمفردة بعد ألحذف‬

‫ثم نعمل على تسمية ألعقدة أالخيرة بألعقدة ألرأس )‪:(last‬‬


‫; ‪last = cur‬‬

‫فتكون ألقائمة ألمتصلة ألجديدة كما في ألشكل ‪٢٤ -١‬‬

‫‪head‬‬ ‫‪last‬‬
‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪6‬‬

‫ألشكل ‪ ٢٤ -١‬ألقائمة ألمتصلة ألمفردة بعد ألحذف‬

‫وأخيرا‪ ،‬نعمل على جعل مؤشر ألعقدة أالخيرة يؤشر على ألفراغ‪ .‬ألصيغة ألبرمجية ھي‪:‬‬

‫;‪last ->link = NULL‬‬

‫فتكون ألقائمة ألمتصلة ألجديدة كما في ألشكل ‪٢٥ -١‬‬


head last

1 2 5 6

‫ ألقائمة ألمتصلة ألمفردة‬٢٥ -١ ‫ألشكل‬

:‫للحصول على ألقائمة ألمتصلة أعاله يمكن تنفيذ ألبرنامج أالتي‬


main( )
{ create( ) ;
read( );
delast( );
clrscr( );
write( ); }

:‫مخرجات ألبرنامج تكون على ألنحو أالتي‬

Data of node [ 0 ] = 1
Data of node [ 1 ] = 2
Data of node [ 2 ] = 5
Data of node [ 3 ] = 6

‫ وألعقدة‬head ‫لحذف عقدة من أية موقع في ألقائمة ألمتصلة ألمفردة ) بإستثناء ألعقدة أالولى‬
:‫ ( نستخدم ألدالة أالتية‬last ‫أالخيرة‬

void deany (int me )


{
assert(head -> Data != me);
assert(last -> Data != me);

nod *ptr;
cur = head ;
while (cur -> Data != me)
{
ptr = cur ;
cur = cur -> link ;
}
ptr -> link = cur -> link ;
delete cur ;
}
‫وكما ذكرنا فإن إستخدام ألدالة ال ينطبق على حذف ألعقدة أالولى أو ألعقدة أالخيرة ولبرمجة ھذا‬
‫أالستثناء تم إستخدام ألدالة ‪ assert‬وألموجودة في ألملف ألرأسي ‪ ، assert.h‬وھذه ألدالة ھي‬
‫إمتداد لجملة ‪ if‬حيث تعمل على إنھاء ألبرنامج عندما ال يتحقق ألشرط‪.‬‬
‫لقد تم إستخدام ألدالة ألستثناء ألعقدتين أالولى وألثانية وكما يلي‪:‬‬

‫;)‪assert(head -> Data != me‬‬


‫;)‪assert(last -> Data != me‬‬

‫فإذا تم إدخال ألقيمة ‪ ١‬وھي ألبيانات ألموجودة في عقدة ألرأس ‪ head‬أو ألقيمة ‪ ٩‬وھي‬
‫ألبيانات ألموجودة في ألعقدة أالخيرة ‪ last‬فسوف تظھر ألصيغة أالتية‪:‬‬

‫‪Assertion failed: head -> Data != me, file filename.CPP, line 5,‬‬

‫أو ألصيغة‬

‫‪Assertion failed: last -> Data != me, file filename.CPP, line 6,‬‬

‫أما إذا كانت ألقيمة غير ذلك فإن ألبرنامج سوف يعمل على أالعالن عن عقدة مؤشرھا ‪ptr1‬‬
‫لتكون ألعقدة ألسابقة للعقدة ألمراد حذفھا‬

‫; ‪nod *ptr1‬‬

‫ويخصص ألمؤشر ‪ cur‬للعقدة ألمراد حذفھا‬


‫; ‪cur = head‬‬

‫ألشكل ‪ ٢٦ -١‬يوضح ذلك‪:‬‬

‫‪head‬‬ ‫‪cur‬‬ ‫‪last‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪6‬‬

‫ألشكل ‪ ٢٦ -١‬ألقائمة ألمتصلة ألمفردة‬

‫وللوصول إلى ألعقد ألمحددة نستخدم جملة ‪ while‬وعلى ألنحو أالتي‪:‬‬

‫)‪while (cur -> Data != me‬‬


‫{‬
‫; ‪ptr1 = cur‬‬
‫; ‪cur = cur -> link‬‬
‫}‬
‫فإذا إفترضنا بأن بيانلت ألعقدة ألمراد حذفھا تساوي ‪ ) ٥‬أي أن ‪ ( me = 5‬فإن ألشكل سيكون‬
‫على ألنحو أالتي‪:‬‬

‫‪head‬‬ ‫‪ptr1‬‬ ‫‪cur‬‬ ‫‪last‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪6‬‬ ‫‪9‬‬

‫ألشكل ‪ ٢٧ -١‬ألمؤشران ‪ptr1 , cur‬‬

‫تبدأ عملية ألحذف بأن نجعل مؤشر ألعقدة ‪ ptr1‬يؤشر على ألعقدة ألتي تلي ألعقدة ذات ألمؤشر‬
‫‪ ،cur‬ألجملة ألتالية توضح ذلك‪:‬‬

‫; ‪ptr1 -> link = cur -> link‬‬

‫ألشكل ‪ ٢٨ -١‬يوضح سير ألعمليات‪:‬‬

‫‪head‬‬ ‫‪ptr1‬‬ ‫‪cur‬‬ ‫‪last‬‬


‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪6‬‬ ‫‪9‬‬

‫ألشكل ‪ ٢٨ -١‬ربط ألعقد ‪ptr1‬‬

‫الحظ كيف فصلت ألعقدة ‪ .cur‬يمكن أالن حذفھا وبسھولة وكما يلي‪:‬‬
‫; ‪delete cur‬‬

‫فتكون ألقائمة ألمتصلة ألجديدة كما في ألشكل ‪٢٩ -١‬‬

‫‪head‬‬ ‫‪last‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪6‬‬ ‫‪9‬‬

‫ألشكل ‪ ٢٩ -١‬ألقائمة ألمتصلة ألجديدة‬

‫للحصول على ألقائمة ألمتصلة أعاله يمكن تنفيذ ألبرنامج أالتي‪:‬‬


‫) (‪main‬‬
‫; ) (‪{ create‬‬
‫;) (‪read‬‬
‫;)‪deany(5‬‬
‫;) (‪clrscr‬‬
‫} ;) (‪write‬‬

‫مخرجات ألبرنامج تكون على ألنحو أالتي‪:‬‬

‫‪Data of node [ 0 ] = 1‬‬


‫‪Data of node [ 1 ] = 2‬‬
‫‪Data of node [ 2 ] = 6‬‬
‫‪Data of node [ 3 ] = 9‬‬

‫مالحظة‪:‬‬

‫لحذف عقدة من أية موقع في ألقائم‪:‬ة ألمتص‪:‬لة يج‪:‬ب أن تحم‪:‬ل نف‪:‬س قيم‪:‬ة ألبيان‪:‬ات وألت‪:‬ي‬
‫تساوي قيمة ألمتغير ‪ ،me‬أي يجب أن تكون ألعقدة ألمراد حذفھا داخل ألقائمة ألمتصلة‪.‬‬

‫تدمير ألقائمة ألمتصلة‪:‬‬


‫يمكن إنشاء دالة تعمل على تدمير ألقائم‪:‬ة ألمتص‪:‬لة وذل‪:‬ك بح‪:‬ذف عق‪:‬دة تل‪:‬و ألعق‪:‬دة مبت‪:‬دئين‬
‫بألعقدة ألرأس وحتى ألعقدة أالخيرة‪:‬‬

‫)(‪void destroy‬‬
‫{‬
‫;)‪If( ! head ) exit(1‬‬
‫; ‪cur = head‬‬
‫)‪while(cur‬‬
‫{‬
‫;‪head = cur -> link‬‬
‫;‪delete cur‬‬
‫;‪cur = head‬‬
‫}‬
‫;"‪cout<<" No linked List exist \n‬‬
‫}‬

‫أإلبتداء للقائمة ألمتصلة‪:‬‬


‫ألدالة ألتالية تعمل على إبتداء) ‪ (initializing‬لقائمة ُمتصلة حيث ستكون فارغة تماما‪:‬‬

‫)(‪void initila‬‬
‫{‬
‫} ;‪head = last = NULL‬‬
‫‪The General Computer Program‬‬ ‫‪ .٧‬ألبرنامج ألعام‬

‫ألبرنامج أألتي ھو برنامج عام وشامل لكافة ألعمليات ألتي يمكن تنفيذھا على ألقائمة ألمتصلة‬
‫ألمفردة‪ ،‬حيث يشمل ألبرنامج على ما يلي‪:‬‬

‫ألمتصلة ألمفردة‬ ‫ِ‬ ‫إنشاء ألقائِمة‬ ‫‬


‫إدخال ألبيانات لكل عقدة‬ ‫‬
‫ألمتصلة ألمفردة‬
‫ِ‬ ‫ألتجول في ألقائِمة‬ ‫‬
‫ألمتصلة‬
‫ِ‬ ‫إبتداء ألقائِمة‬ ‫‬
‫إضافة عقدة جديدة عند ألرأس‬ ‫‬
‫إضافة عقدة جديدة بعد ألعقدة أالخيرة‬ ‫‬
‫لمتصلة‬
‫ِ‬ ‫إضافة عقدة جديدة في أية مكان من ألقائِمة أ‬ ‫‬
‫ألمتصلة ألمفردة‬
‫ِ‬ ‫حذف ألعقدة أالولى من ألقائِمة‬ ‫‬
‫ألمتصلة ألمفردة‬
‫ِ‬ ‫حذف ألعقدة أالخيرة من ألقائِمة‬ ‫‬
‫ألمتصلة ألمفردة‬
‫ِ‬ ‫حذف أية عقدة من ألقائِمة‬ ‫‬
‫ألمتصلة‬
‫ِ‬ ‫تدمير ألقائِمة‬ ‫‬

‫‪// Program Chr1_01.cpp‬‬

‫>‪# include<iostream.h‬‬
‫>‪# include<conio.h‬‬
‫>‪# include<stdlib.h‬‬
‫>‪# include<assert.h‬‬

‫{ ‪class nod‬‬
‫‪public:‬‬
‫; ‪int Data‬‬
‫; ‪nod *link‬‬
‫;}‬

‫{ ‪class SLL‬‬
‫‪public:‬‬
‫} ;‪SLL(int s){size = s‬‬

‫‪// Function for the initialization of the Linked List‬‬


‫)(‪void initila‬‬
‫{‬
‫;‪head = last = NULL‬‬
‫}‬

‫‪// Function for creating the Linked List‬‬


‫) ( ‪void create‬‬
{
head = new nod ;
cur = head ;
for (int i = 1 ; i <= size ; i++ )
{
cur -> link = new nod ;
cur = cur -> link ;
}
last = cur ;
last -> link = NULL ;
}

// Function for inserting data for each node in the Linked List
void read ( )
{
cout<< "Enter the value for the head : " ;
cin>> head -> Data ;
cur = head ;
while( cur->link)
{
cout<< " Enter the value of the item : " ;
cur = cur -> link ;
cin>> cur -> Data ;
}
}

// Function for traversing the Linked List


void write( )
{
int l = 0;
cur = head ;
while (cur)
{
cout<< "Data of node [ " <<l++<<" ] = "
<<cur->Data<<endl;
cur = cur -> link;
}
}

// Function for adding a new node at the beginning of the Linked List
void adfirst(int m)
{
if( !head )
{
head = new nod;
head->Data = m;
last = head;
last -> link = NULL;
}
else
{
nod *temp = new nod;
temp -> Data = m;
temp -> link =head;
head = temp;
}
}

// Function for adding a new node at the end of the Linked List
void adend(int n)
{
if( !head )
{
head = new nod;
head->Data = n;
head -> link = NULL;
last = head;
}
else
{
nod *temp = new nod;
temp -> Data = n;
last -> link = temp;
last = temp;
last -> link = NULL ;
}
}

// Function for adding a new node at any place of the Linked List
void adany (int me)
{
nod *temp, *ptr ;
temp = new nod ;
temp -> Data = me ;
cur = head ;
while (cur -> Data < me )
{
ptr = cur ;
cur = cur -> link ;
}
ptr ->link = temp;
temp -> link = cur ;
}

// Function for deleting a node from the beginning of the Linked List
void defirst( )
{
cur = head;
head = head -> link;
delete cur;
}

// Function for deleting a node from the end of the Linked List
void delast( )
{
cur = head ;
while (cur -> link != last )
cur = cur -> link;
delete last;
last = cur ;
last -> link = NULL;
}

// Function for deleting a node from any place of the Linked List
void deany (int me )
{
assert(head -> Data != me);
assert(last -> Data != me);
nod *ptr;
cur = head ;
while (cur -> Data != me)
{
ptr = cur ;
cur = cur -> link ;
}
ptr -> link = cur -> link ;
delete cur ;
}
// Function for destroying the Linked List
void destroy()
{
cur = head ;
while(cur)
{

head = cur -> link ;


delete cur ;
cur = head ;
}
cout<<" No linked List exist \n" ;
}

private:
int size;
nod *head, *cur, *last ;
};
SLL x(4);

main( )
{ x.create ( ) ;
x.read();
clrscr( ) ;
char ch;
int m;
cout<<" \n SELECT A CHARACTER TO RUN ONE OF THE FOLLOWING: "<<endl;
cout<<" ______________________________________________ \n"<<endl;
cout<<" a: for the initialization of the Linked List"<<endl;
cout<<" b: for adding a new node at the beginning of the Linked List "<<endl;
cout<<" c: for adding a new node at the end of the Linked List "<<endl;
cout<<" d: for adding a new node at any place of the Linked List"<<endl;
cout<<" e: for deleting a node from the beginning of the Linked List"<<endl;
cout<<" f: for deleting a node from the end of the Linked List"<<endl;
cout<<" g: for deleting a node from any place of the Linked List"<<endl;
cout<<" h: for destroying the Linked List"<<endl;
cin>>ch;
switch(ch)
{
case 'a': {clrscr( );
x.initila( ) ;
x.write( );
break;}

case 'b': {clrscr( );


cout<<" Enter the data for the new node ( First node) :";
cin>>m;
x.adfirst(m);
x.write();
break;}

case 'c': {clrscr( );


cout<<" Enter the data for the new node ( Last node) :";
cin>>m;
x.adend(m);
x.write();
break;}

case 'd': {clrscr( );


cout<<" Enter the data for the new node ( Any place ) \n"
<<" You have to select the new node within the data: " ;
cin>>m;
x.adany(m);
x.write();
break;}

case 'e': {clrscr( );


x.defirst();
x.write();
break;}

case 'f': {clrscr( );


x.delast();
x.write();
break;}

case 'g': {clrscr( );


cout<<" Enter the data for the node (Any place) \n"
<<" You have to select the node within the Linked List: " ;
cin>>m;
x.deany(m);
x.write();
break; }

case 'h': {clrscr( );


x.destroy( );
x.write( );
break;}

default: {clrscr( ) ;
exit(5);
}
}
}

ِ ‫ سوف تُنشأ قائمة متصلة مفردة ويُطلب ِمنا إدخال ألبيانات‬،‫عند تنفيذ ألبرنامج‬
‫لكل ِ◌ ِ◌ عقدة مبتدا‬
.‫من ألرأس ثم ألمرور بأل ُعقد ألباقية حتى أألخيرة‬
:‫بعد ذلك سوف تظھر لنا ألشاشة ألتالية‬

SELECT A CHARACTER TO RUN ONE OF THE FOLLOWING:


__________________________________________

a: for the initialization of the Linked List


b: for adding a new node at the beginning of the Linked List
c: for adding a new node at the end of the Linked List
d: for adding a new node at any place of the Linked List
e: for deleting a node from the beginning of the Linked List
f: for deleting a node from the end of the Linked List
g: for deleting a node from any place of the Linked List
h: for destroying the Linked List

‫ ( وبخالف ذلك سوف نخرج من‬h ‫ إلى‬a ‫حيث يتوجب علينا إختيار واحد من ألحروف ) من‬
.‫ألبرنامج‬
‫ وألتي‬switch ‫إن كل حرف من ألحروف أعاله يدل على عملية يتم تنفيذھا بإستخدام عبارة‬
‫ سوف يعمل على تنفيذ كافة ألجمل في‬case ‫ ألمطلوبة وبدورھا فإن أالمر‬case ‫تتضمن ألحالة‬
.‫( وألتي تكون من ضمنھا ألدالة ألرئيسية لتنفيذ ألعملية‬block) ‫داخل ألكتلة‬
‫‪Circular Linked List‬‬ ‫‪ .٨‬ألقائمة ألمتصلة ألدورانية‬

‫في ألمناقشات ألسابقة الحظنا بأن ألقائمة ألمتصلة ألمفردة يؤشر فيھا مؤشر ألعقدة أالخيرة ‪last‬‬
‫على ألفراغ ‪ .NULL‬أما إذا أشر مؤشر ألعقدة أالخيرة على ألعقدة أالولى فإن ألقائمة ألمتصلة‬
‫سوف تسمى ألقائمة ألمتصلة ألدورانية )‪ .(Circular‬ألشكل ‪ ٣٠ -١‬يوضح ذلك‪:‬‬

‫‪head‬‬ ‫‪last‬‬

‫ألشكل ‪ ٣٠-١‬ألقائمة ألمتصلة ألدورانية‬

‫وعليه‪ ،‬النشاء قائمة متصلة دورانية ناتبع ألخطوات ألبرمجية أالتية‪:‬‬

‫‪// Program Chr1_02.cpp‬‬


‫>‪# include<iostream.h‬‬

‫{ ‪struct nod‬‬
‫; ‪int Data‬‬
‫; ‪nod *link‬‬
‫;}‬
‫; ‪nod *head, *cur, *last‬‬

‫) ( ‪void create_Cir‬‬
‫{‬
‫; ‪head = new nod‬‬
‫; ‪cur = head‬‬
‫) ‪for (int i = 1 ; i < 4 ; i++‬‬
‫{‬
‫; ‪cur -> link = new nod‬‬
‫; ‪cur = cur -> link‬‬
‫}‬
‫; ‪last = cur‬‬
‫; ‪last -> link = head‬‬
‫}‬

‫) (‪main‬‬
‫} ; ) ( ‪{ create_Cir‬‬
‫لم يختلف ألبرنامج ألحالي ‪ Program Chr1_02.cpp‬عن ألبرنامج أالول ‪Program‬‬
‫‪ Chr1_01.cpp‬سوى جملة واحدة فقط وھي‪:‬‬

‫; ‪last -> link = head‬‬

‫حيث تم ربط ألعقدة أالخيرة بألعقدة أالولى‪ ،‬فأصبحت ألقائمة ألمتصلة دورانية )‪.(Circular‬‬

‫ألدخال ألبيانات‪ ،‬نستخدم ألدالة ألتالية‪:‬‬


‫) ( ‪void read_Cir‬‬
‫{‬
‫; " ‪cout<< "Enter the value for the head :‬‬
‫; ‪cin>> head -> Data‬‬
‫; ‪cur = head‬‬
‫)‪while( cur->link != head‬‬
‫; " ‪{ cout<< " Enter the value for each item :‬‬
‫; ‪cur = cur -> link‬‬
‫; ‪cin>> cur -> Data‬‬ ‫}‬
‫}‬

‫فإذا تم إدخال ألبيانات أالتية ‪:‬‬

‫ ‪١‬‬
‫ ‪٦ ،٥ ،٢‬‬

‫وعلية فإن ألقائمة ألمتصلة ألدورانية تكون بألشكل ‪٣١ -١‬‬

‫‪head‬‬ ‫‪last‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪6‬‬

‫ألشكل ‪ ٣١ -١‬بيانات ألقائمة ألمتصلة ألدورانية‬

‫ألتجول في قائمة متصلة دورانية ھو زيارة كل عقدة من عقد ألقائمة مبتدئين بألرأس حتى ألعقدة‬
‫أالخيرة‪ .‬ألتركيب ألخاص للدالة يكون على ألنحو أالتي‪:‬‬

‫) (‪void write_Cir‬‬
‫{‬
‫;‪int l = 0‬‬
‫; ‪cur = head‬‬
‫" = ] "<<‪cout<< "Data of node [ " <<l++‬‬
‫;‪<<head->Data<<endl‬‬
‫)‪while (cur ->link != head‬‬
‫{‬
‫;‪cur = cur -> link‬‬
‫" = ] "<<‪cout<< "Data of node [ " <<l++‬‬
‫;‪<<cur->Data<<endl‬‬
‫}‬
‫}‬

‫مخرجات ألبرنامج تكون على ألنحو أالتي‪:‬‬

‫‪Data of node [ 0 ] = 1‬‬


‫‪Data of node [ 1 ] = 2‬‬
‫‪Data of node [ 2 ] = 5‬‬
‫‪Data of node [ 3 ] = 6‬‬

‫‪ .٩‬ألعمليات أالساسية على ألقائمة ألمتصلة ألدورانية‬


‫‪Basic Operations on Circular Linked List‬‬

‫يتضمن ھذا ألجزء من ألفصل ألمواضيع أالتية‪:‬‬

‫‪ o‬حشر ‪ insert‬عقدة في موقع معين من ألقائمة ألمتصلة ألدورانية‬


‫‪ o‬حذف ‪ delete‬عقدة من موقع معين في ألقائمة ألمتصلة ألدورانية‬
‫‪ o‬إبتداء وتدمير ألقائمة ألمتصلة ألدورانية‬

‫حشر عقدة‪:‬‬
‫لحشر عقدة جديدة في بداية ألقائمة ألمتصلة ألدورانية نستخدم ألدالة أالتية‪:‬‬

‫)‪void adfirst_Cir(int m‬‬


‫{‬
‫) ‪if( !head‬‬
‫{‬
‫;‪head = new nod‬‬
‫;‪head->Data = m‬‬
‫;‪last = head‬‬
‫;‪last -> link = head‬‬
‫}‬
‫‪else‬‬
‫{‬
‫;‪nod *temp = new nod‬‬
‫;‪temp -> Data = m‬‬
‫;‪temp -> link =head‬‬
‫;‪head = temp‬‬
‫;‪last -> link = head‬‬
‫}‬
‫}‬

‫وكما ذكرنا سابقا‪،‬فإن ألجزء ألجزء أالول من ألدالة ينفذ عند عدم إحتواء ألقائمة ألمتصلة‬
‫ألدورانية على أية عقدة وعليه فإن ألعقدة ألجديدة ستكون ھي ألعقدة ألرأس وھي ألعقدة أالخيرة‬
‫في نفس ألوقت‪ .‬في حين إن لم تكن ألقائمة ألمتصلة ألدورانية خالية فإننا نستطيع إضافة ألعقدة‬
‫ألجديدة في ألموقع ألمناسب‪.‬‬
‫ألشكل ‪ ٣٢ -١‬يوضح ألعبارتين من أالمر ‪ else‬وھي‪:‬‬

‫;‪nod *temp = new nod‬‬


‫;‪temp -> Data = m‬‬

‫‪head‬‬ ‫‪last‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪6‬‬

‫‪temp‬‬

‫‪m‬‬
‫‪*temp‬‬
‫ألشكل ‪ ٣٢ -١‬إضافة عقدة جديدة لقائمة متصلة دورانية‬

‫أما ألعبارتين أالخيرتين‪:‬‬


‫;‪temp -> link =head‬‬
‫;‪head = temp‬‬

‫فھي تعمل على ربط ألعقدة ألجديدة بألعقدة ألرأس ثم يتم إطالق إسم ألرأس على ألعقدة ألجديدة‪.‬‬
‫ألشكل ‪ ٣٣ - ١‬يوضح ذلك‬

‫‪last‬‬
‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪6‬‬

‫‪head‬‬
‫‪m‬‬

‫ألشكل ‪ ٣٣-١‬ألقائمة ألمتصلة ألدورانية بعد ألربط‬


‫يمكن إضافة ھذه ألدالة ليكون ألجزء ألتنفيذي للبرنامج على ألنحو أالتي‪:‬‬

‫) (‪main‬‬
‫{‬
‫; ) ( ‪create_Cir‬‬
‫;) ( ‪Read_Cir‬‬
‫;) ( ‪clrscr‬‬
‫;) ( ‪write_Cir‬‬
‫;"‪cout<<" Enter the Data for the new first node :‬‬
‫;‪cin>>m‬‬
‫;)‪Adfirst_Cir(m‬‬
‫;) ( ‪clrscr‬‬
‫;) ( ‪write_Cir‬‬
‫}‬

‫فإذا كانت قيمة ألبيانات للعقدة ألجديدة ھي ‪ m = 0‬فإن مخرجات ألبرنامج تكون على ألنحو‬
‫أالتي‪:‬‬

‫‪Data of node [ 0 ] = 0‬‬


‫‪Data of node [ 1 ] = 1‬‬
‫‪Data of node [ 2 ] = 2‬‬
‫‪Data of node [ 3 ] = 5‬‬
‫‪Data of node [ 4 ] = 6‬‬

‫ألشكل ألتالي يوضح لنا ألقائمة ألمتصلة ألدورانية ألجديدة‬

‫‪head‬‬ ‫‪last‬‬

‫‪0‬‬ ‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪6‬‬

‫ألشكل ‪ ٣٤ -١‬ألقائمة ألمتصلة ألدورانية ألجديدة‬

‫أما عند إضافة عقدة جديدة في نھاية ألقائمة ألمتصلة ألدورانية فيمكن تطبيق ألدالة أالتية‪:‬‬

‫)‪void addend_Cir(int n‬‬


‫{‬
‫) ‪if( !last‬‬
‫{‬
‫;‪last = new nod‬‬
‫;‪last->Data = n‬‬
‫;‪head = last‬‬
‫;‪last -> link = head‬‬
‫}‬
‫‪else‬‬
‫{‬
‫;‪nod *temp = new nod‬‬
‫;‪temp -> Data = n‬‬
‫;‪last -> link = temp‬‬
‫;‪last = temp‬‬
‫; ‪last -> link = head‬‬
‫}‬
‫}‬

‫وكم‪:‬ا ذكرن‪:‬ا س‪:‬ابقا وب‪:‬إفتراض ب‪:‬أن ألج‪:‬زء أالول م‪::‬ن ألدال‪:‬ة يتعام‪:‬ل م‪:‬ع قائم‪:‬ة متص‪:‬لة دوراني‪::‬ة ال‬
‫تحتوي على أية عقدة وعليه فإن ألعقدة ألجديدة ستكون ھي ألعق‪:‬دةأالخيرة وھ‪:‬ي ألعق‪:‬دة أل‪:‬رأس ف‪:‬ي‬
‫نف‪::‬س ألوق‪::‬ت‪ .‬ف‪::‬ي ح‪::‬ين إن ل‪::‬م تك‪::‬ن ألقائم‪::‬ة ألمتص‪::‬لة ألدوراني‪::‬ة خالي‪::‬ة فإنن‪::‬ا نس‪::‬تطيع إض‪::‬افة ألعق‪::‬دة‬
‫ألجديدة‪.‬‬

‫ألشكل‪ ٣٥ - ١‬يوضح ألعبارتين من أالمر ‪ else‬وھي‪:‬‬

‫;‪nod *temp = new nod‬‬


‫;‪temp -> Data = n‬‬

‫‪head‬‬ ‫‪last‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪6‬‬

‫‪temp‬‬
‫‪n‬‬
‫‪*temp‬‬
‫ألشكل ‪ ٣٥ -١‬إلضافة عقدة جديدة لقائمة متصلة دورانية‬

‫أما ألعبارات‪:‬‬

‫;‪last-> link = temp‬‬


‫;‪last = temp‬‬
‫;‪last -> link = head‬‬

‫فھي تعمل على ربط ألعقدة أالخيرة بألعقدة ألجديدة )‪ (*temp‬ثم يتم إطالق إسم أالخيرعلى ألعقدة‬
‫ألجديدة‪ .‬أما ألعبارة أالخيرة فإنھا تعمل على جعل مؤشر ألعقدة أالخيرة يؤشر على ألعقدة ألرأس‪.‬‬
‫ألشكل ‪ ٣٦ -١‬يوضح ذلك‬

‫‪head‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪6‬‬

‫‪last‬‬

‫‪n‬‬

‫ألشكل ‪ ٣٦ -١‬ألقائمة ألمتصلة ألدورانية ألجديدة‬

‫يمكن إضافة ھذه ألدالة ليكون ألجزء ألتنفيذي للبرنامج على ألنحو أالتي‪:‬‬

‫) (‪main‬‬
‫; ) ( ‪{ create_Cir‬‬
‫;) ( ‪Read_Cir‬‬
‫;) ( ‪clrscr‬‬
‫;) ( ‪write_Cir‬‬
‫;"‪cout<<" Enter the Data for the new end node :‬‬
‫;‪cin>>n‬‬
‫;)‪Addend_Cir(n‬‬
‫;) ( ‪clrscr‬‬
‫;) (‪write_Cir‬‬ ‫}‬

‫فإذا كانت قيمة ألبيانات للعقدة ألجديدة ھي ‪ n = 8‬فإن مخرجات ألبرنامج تكون على ألنحو‬
‫أالتي‪:‬‬

‫‪Data of node [ 0 ] = 1‬‬


‫‪Data of node [ 1 ] = 2‬‬
‫‪Data of node [ 2 ] = 5‬‬
‫‪Data of node [ 3 ] = 6‬‬
‫‪Data of node [ 4 ] = 8‬‬

‫ألشكل ألتالي يوضح لنا ألقائمة ألمتصلة ألدورانية ألجديدة‬

‫‪head‬‬ ‫‪last‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪6‬‬ ‫‪8‬‬

‫ألشكل ‪ ٣٦ -١‬ألقائمة ألمتصلة ألدورانية ألجديدة‬


‫وإلضافة عقدة جديدة في مكان ما من ألقائمة ألمتصلة ألدورانية يمكن تطبيق ألدالة أالتية‪:‬‬

‫)‪void adany_Cir (int me‬‬


‫{‬
‫; ‪nod *temp, *ptr‬‬
‫; ‪temp = new nod‬‬
‫; ‪temp -> Data = me‬‬
‫; ‪cur = head‬‬
‫) ‪while (cur -> Data < me‬‬
‫{‬
‫; ‪ptr = cur‬‬
‫; ‪cur = cur -> link‬‬
‫}‬
‫;‪ptr ->link=temp‬‬
‫; ‪temp->link = cur‬‬
‫}‬

‫الحظ بأن ألدالة شبيھة تماما للدالة ‪ adany‬وألتي تم إستخدامھا عند ألتعامل مع ألقائمة ألمتصلة‬
‫ألمفردة فألدالة أعاله تعمل تحديد موقع ألعقدة ألجديدة وذلك بمعرفة ألعقدة ألتي قبلھا ‪ ptr‬وألعقدة‬
‫ألتي بعدھا ‪ ، cur‬ويتم تحديد ذلك بإستخدام ألصيغة ‪ while‬حيث تحدد قيمة ألعقدة ألسابقة‬
‫بألعبارة‬
‫; ‪ptr = cur‬‬

‫وتحدد ألقيمة ألتالية بألعبارة‬

‫; ‪cur = cur -> link‬‬

‫مالحظة‪:‬‬
‫وكما ذكرنا سابقا فإن ألدالة أعاله صحيحة عندما تكون ألبيانات مرتبة ترتيبا تصاعديا‪.‬‬
‫ألشكل ‪ ٣٧ -١‬يوضح إجراء عملية إضافة ألعقدة ألجديدة‪:‬‬

‫‪head‬‬ ‫‪ptr‬‬ ‫‪cur‬‬ ‫‪last‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪6‬‬

‫‪temp‬‬

‫‪3‬‬
‫ألشكل ‪ ٣٧ -١‬ألقائمة ألمتصلة ألدورانية ألجديدة‬
‫فإذا كانت قيمة ألبيانات للعقدة ألجديدة ھي ‪ me = 3‬فإن مخرجات ألبرنامج تكون على ألنحو‬
‫أالتي‪:‬‬
‫‪Data of node [ 0 ] = 1‬‬
‫‪Data of node [ 1 ] = 2‬‬
‫‪Data of node [ 2 ] = 3‬‬
‫‪Data of node [ 3 ] = 5‬‬
‫‪Data of node [ 4 ] = 6‬‬

‫ألشكل ألتالي يوضح لنا ألقائمة ألمتصلة ألدورانية ألجديدة‬

‫‪head‬‬ ‫‪last‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪٣‬‬ ‫‪٥‬‬ ‫‪٦‬‬

‫ألشكل ‪ ٣٨ -١‬ألقائمة ألمتصلة ألدورانية ألجديدة‬

‫حذف عقدة‪:‬‬
‫إن عملية حذف عقدة من قائمة متصلة دورانية تشبه عملية حذف عقدة من قائمة متصلة مفردة‪.‬‬
‫فألحذف سيكون من ألمواقع أالتية‪:‬‬

‫ بداية ألقائمة ألمتصلة ألدورانية‬


‫ أية موقع من ألقائمة ألمتصلة ألدورانية‬
‫ نھاية ألقائمة ألمتصلة ألدورانية‬

‫لحذف عقدة من بداية ألقائمة ألمتصلة ألدورانية نستخدم ألدالة أالتية‪:‬‬

‫) (‪void defirst_Cir‬‬
‫{‬
‫;‪cur = head‬‬
‫;‪head = head -> link‬‬
‫;‪delete cur‬‬
‫;‪last - > link = head‬‬
‫}‬
‫عند تطبيق ھذه ألدالة لحذف ألعقدة ألرأس من ألقائمة ألمتصلة ألمفردة فإن أولى ألخطوات ھي‬
‫تسمية ألعقدة ألرأس بألعقدة تيار )‪:(cur‬‬

‫; ‪cur = head‬‬

‫أما ألعبارة‬
‫;‪head = head -> link‬‬
‫فتعمل على نقل ألمؤشر ‪ head‬إلى ألعقدة ألتالية‬
‫وألخطوة ما قبل أالخيرة تعمل على حذف ألعقدة ‪cur‬‬
‫;‪delete cur‬‬

‫وألخطوة أألخيرة ھي ربط أألعقدة أألخيرة بألعقدة ألرأس عندھا سيكون ألشكل ألنھائي للقائمة‬
‫ألمتصلة ألدورانية ستكون على ألنحو أالتي‪:‬‬

‫‪head‬‬ ‫‪last‬‬

‫‪2‬‬ ‫‪5‬‬ ‫‪٦‬‬

‫ألشكل ‪ ٣٩ -١‬ألقائمة ألمتصلة ألدورانية بعد ألحذف‬

‫وللحصول على ألبيانات يمكن تطبيق ألبرنامج أالتي‬

‫) (‪main‬‬
‫; ) (‪{ create_Cir‬‬
‫;) (‪read_Cir‬‬
‫;) (‪defirst_Cir‬‬
‫;) (‪clrscr‬‬
‫} ;) (‪write_Cir‬‬

‫مخرجات ألبرنامج تكون على ألنحو أالتي‪:‬‬

‫‪Data of node [ 0 ] = 2‬‬


‫‪Data of node [ 1 ] = 5‬‬
‫‪Data of node [ 2 ] = 6‬‬

‫لحذف عقدة من نھاية ألقائمة ألمتصلة أدورانية نستخدم ألدالة أالتية‪:‬‬

‫) (‪void delast_Cir‬‬
‫{‬
‫; ‪cur = head‬‬
‫) ‪while (cur -> link != last‬‬
‫;‪cur = cur -> link‬‬
‫;‪delete last‬‬
‫; ‪last = cur‬‬
‫;‪last -> link = head‬‬
‫}‬
‫فألعبارة أالولى‬
‫; ‪cur = head‬‬

‫تعمل على تسمية ألعقدة ألرأس بألعقدة ألتيار )‪ .(cur‬وللوصول إلى ألعقدة ألتي تسبق ألعقدة‬
‫أالخيرة نطبق ألصيغة أالتية‪:‬‬

‫) ‪while (cur -> link !=last‬‬


‫;‪cur = cur -> link‬‬

‫حيث ستتوقف جملة ‪ while‬عندما تؤشر ألعقدة ‪ cur‬على ألعقدة أالخيرة ‪ .‬نستطيع أالن‬
‫وبسھولة تنفيذ ألجملة‪:‬‬
‫;‪delete last‬‬

‫وذلك لحذف ألعقدة أالخيرة‪.‬‬

‫ألشكل ‪ ٤٠ -١‬يبين ألقائمة ألمتصلة ألدورانية ألجديدة‬

‫‪head‬‬ ‫‪cur‬‬

‫‪١‬‬ ‫‪٢‬‬ ‫‪٥‬‬

‫ألشكل ‪ ٤٠ -١‬ألقائمة ألمتصلة ألدورانية بعد ألحذف‬

‫ثم نعمل على تسمية ألعقدة أالخيرة بألعقدة ألرأس )‪:(last‬‬


‫; ‪last = cur‬‬

‫وأخيرا‪ ،‬نعمل على جعل مؤشر ألعقدة أالخيرة يؤشر على ألعقدة ألرأس‪ .‬ألصيغة ألبرمجية ھي‪:‬‬

‫;‪last ->link = head‬‬

‫فتكون ألقائمة ألمتصلة ألجديدة كما في ألشكل ‪41 -١‬‬

‫‪head‬‬ ‫‪last‬‬

‫‪١‬‬ ‫‪٢‬‬ ‫‪٥‬‬

‫ألشكل ‪ ٤١ -١‬ألقائمة ألمتصلة ألدورانية‬

‫للحصول على ألقائمة ألمتصلة أعاله يمكن تنفيذ ألبرنامج أالتي‪:‬‬


‫) (‪main‬‬
‫; ) (‪{ create_Cir‬‬
‫;) (‪read_Cir‬‬
‫;) (‪delast_Cir‬‬
‫;) (‪clrscr‬‬
‫;) (‪write_Cir‬‬
‫}‬

‫مخرجات ألبرنامج تكون على ألنحو أالتي‪:‬‬

‫‪Data of node [ 0 ] = 1‬‬


‫‪Data of node [ 1 ] = 2‬‬
‫‪Data of node [ 2 ] = 5‬‬

‫لحذف عقدة من أية موقع في ألقائمة ألمتصلة ألمفردة ) بإستثناء ألعقدة أالولى ‪ head‬وألعقدة‬
‫أالخيرة ‪ ( last‬نستخدم ألدالة أالتية‪:‬‬

‫) ‪void deany_Cir (int me‬‬


‫{‬
‫;)‪assert(head -> Data != me‬‬
‫;)‪assert(last -> Data != me‬‬

‫;‪nod *ptr‬‬
‫; ‪cur = head‬‬
‫)‪while (cur -> Data != me‬‬
‫{‬
‫; ‪ptr = cur‬‬
‫; ‪cur = cur -> link‬‬
‫}‬
‫; ‪ptr -> link = cur -> link‬‬
‫; ‪delete cur‬‬
‫}‬

‫وكما ذكرنا فإن إستخدام ألدالة ال ينطبق على حذف ألعقدة أالولى أو ألعقدة أالخيرة ولبرمجة ھذا‬
‫أالستثناء تم إستخدام ألدالة ‪ assert‬وألموجودة في ألملف ألرأسي ‪ ، assert.h‬وھذه ألدالة ھي‬
‫إمتداد لجملة ‪ if‬حيث تعمل على إنھاء ألبرنامج عندما ال يتحقق ألشرط‪.‬‬
‫لقد تم إستخدام ألدالة ألستثناء ألعقدتين أالولى وألثانية وكما يلي‪:‬‬

‫;)‪assert(head -> Data != me‬‬


‫;)‪assert(last -> Data != me‬‬
‫فإذا تم إدخال ألقيمة ‪ ١‬وھي ألبيانات ألموجودة في عقدة ألرأس ‪ head‬أو ألقيمة ‪ 6‬وھي‬
‫ألبيانات ألموجودة في ألعقدة أالخيرة ‪ last‬فسوف تظھر ألصيغة أالتية‪:‬‬

‫‪Assertion failed: head -> Data != me, file filename.CPP, line 5,‬‬

‫أو ألصيغة‬

‫‪Assertion failed: last -> Data != me, file filename.CPP, line 6,‬‬

‫أما إذا كانت ألقيمة غير ذلك فإن ألبرنامج سوف يعمل على أالعالن عن عقدة مؤشرھا ‪ptr1‬‬
‫لتكون ألعقدة ألسابقة للعقدة ألمراد حذفھا‬

‫; ‪nod *ptr1‬‬

‫ويخصص ألمؤشر ‪ cur‬للعقدة ألمراد حذفھا‬


‫; ‪cur = head‬‬

‫وللوصول إلى ألعقد ألمحددة نستخدم جملة ‪ while‬وعلى ألنحو أالتي‪:‬‬

‫)‪while (cur -> Data != me‬‬


‫{‬
‫; ‪ptr1 = cur‬‬
‫; ‪cur = cur -> link‬‬
‫}‬

‫فإذا إفترضنا بأن بيانلت ألعقدة ألمراد حذفھا تساوي ‪ ) ٥‬أي أن ‪ ( me = 5‬فإن ألشكل سيكون‬
‫على ألنحو أالتي‪:‬‬

‫‪head‬‬ ‫‪ptr1‬‬ ‫‪cur‬‬ ‫‪last‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪6‬‬

‫ألشكل ‪ ٤٢ -١‬ألمؤشران ‪ptr1 , cur‬‬

‫تبدأ عملية ألحذف بأن نجعل مؤشر ألعقدة ‪ ptr1‬يؤشر على ألعقدة ألتي تلي ألعقدة ذات ألمؤشر‬
‫‪ ،cur‬ألجملة ألتالية توضح ذلك‪:‬‬

‫; ‪ptr1 -> link = cur -> link‬‬

‫ألشكل ‪ ٤٣ -١‬يوضح سير ألعمليات‪:‬‬


‫‪head‬‬ ‫‪ptr1‬‬ ‫‪cur‬‬ ‫‪last‬‬
‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪6‬‬

‫ألشكل ‪ ٤٣ -١‬تحديد ألعقدة ألمراد حذفھا‬

‫الحظ كيف فصلت ألعقدة ‪ .cur‬يمكن أالن حذفھا وبسھولة وكما يلي‪:‬‬
‫; ‪delete cur‬‬
‫فتكون ألقائمة ألمتصلة ألجديدة كما في ألشكل ‪٤٤ -١‬‬

‫‪head‬‬ ‫‪last‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪6‬‬

‫ألشكل ‪ 44 -١‬ألقائمة ألمتصلة ألجديدة‬

‫للحصول على ألقائمة ألمتصلة أعاله يمكن تنفيذ ألبرنامج أالتي‪:‬‬


‫) (‪main‬‬
‫; ) (‪{ create_Cir‬‬
‫;) (‪read_Cir‬‬
‫;)‪deany_Cir(5‬‬
‫;) (‪clrscr‬‬
‫} ;) (‪write_Cir‬‬

‫مخرجات ألبرنامج تكون على ألنحو أالتي‪:‬‬

‫‪Data of node [ 0 ] = 1‬‬


‫‪Data of node [ 1 ] = 2‬‬
‫‪Data of node [ 2 ] = 6‬‬

‫مالحظة‪:‬‬

‫لحذف عقدة من أية موقع في ألقائم‪:‬ة ألمتص‪:‬لة يج‪:‬ب أن تحم‪:‬ل نف‪:‬س قيم‪:‬ة ألبيان‪:‬ات وألت‪:‬ي‬
‫تساوي قيمة ألمتغير ‪ ،me‬أي يجب أن تكون ألعقدة ألمراد حذفھا داخل ألقائمة ألمتصلة‪.‬‬
‫تدمير ألقائمة ألمتصلة‪:‬‬
‫يمكن إنشاء دالة تعمل على تدمير ألقائمة ألمتصلة ألدورانية وذلك بح‪:‬ذف عق‪:‬دة تل‪:‬و ألعق‪:‬دة‬
‫مبتدئين بألعقدة ألرأس وحتى ألعقدة أالخيرة‪:‬‬

‫)(‪void destroy_Cir‬‬
‫{‬
‫;)‪if(! head ) exit(1‬‬
‫; ‪cur = head‬‬
‫)‪while(cur -> link != head‬‬
‫{‬
‫;‪head = cur -> link‬‬
‫;‪delete cur‬‬
‫;‪cur = head‬‬
‫}‬
‫;"‪cout<<" No linked List exist \n‬‬
‫}‬

‫أإلبتداء للقائمة ألمتصلة‪:‬‬


‫ألدالة ألتالية تعمل على إبتداء لقائمة ُمتصلة حيث ستكون فارغة تماما‪:‬‬

‫)(‪void initila_Cir‬‬
‫{‬
‫} ; ‪head = last = NULL‬‬

‫‪The General Computer Program‬‬ ‫‪ .١٠‬ألبرنامج ألعام‬

‫ألبرنامج أألتي ھو برنامج عام وشامل لكافة ألعمليات ألتي يمكن تنفيذھا على ألقائمة ألمتصلة‬
‫ألمفردة‪ ،‬حيث يشمل ألبرنامج على ما يلي‪:‬‬

‫إنشاء ألقائمة ألمتصلة ألدورانية‬ ‫‬


‫إدخال ألبيانات لكل عقدة‬ ‫‬
‫ألتجول في ألقائمة ألمتصلة ألدورانية‬ ‫‬
‫إبتداء ألقائمة ألمتصلة ألدورانية‬ ‫‬
‫إضافة عقدة جديدة عند ألرأس‬ ‫‬
‫إضافة عقدة جديدة بعد ألعقدة أالخيرة‬ ‫‬
‫إضافة عقدة جديدة في أية مكان من ألقائمة ألدورانية‬ ‫‬
‫حذف ألعقدة أالولى من ألقائمة ألمتصلة ألدورانية‬ ‫‬
‫حذف ألعقدة أالخيرة من ألقائمة ألمتصلة ألدورانية‬ ‫‬
‫حذف أية عقدة من ألقائمة ألمتصلة ألدورانية‬ ‫‬
‫تدمير ألقائمة ألمتصلة ألدورانية‬ ‫‬
// Program Chr١_٠٢.cpp

# include<iostream.h>
# include<conio.h>
# include<stdlib.h>
# include<assert.h>

class nod {
public:
int Data ;
nod *link ;
};

class SLL {
public:
SLL(int s){size = s; }

// Function for the initialization of the Circular Linked List


void initila_Cir( )
{
head = last = NULL ; }

// Function for creating the Circular Linked List


void create_Cir ( )
{
head = new nod ;
cur = head ;
for (int i = 1 ; i <= size ; i++ )
{
cur -> link = new nod ;
cur = cur -> link ;
}
last = cur ;
last -> link = head ;
}

// Function for inserting data for each node in the Circular Linked List
void read_Cir ( )
{
cout<< "Enter the value for the head : " ;
cin>> head -> Data ;
cur = head ;
while( cur->link != head)
{
cout<< " Enter the value of the item : " ;
cur = cur -> link ;
cin>> cur -> Data ;
}
}

// Function for traversing the Circular Linked List


void write_Cir( )
{
int l = 0;
cur = head ;
cout<< "Data of node [ " <<l++<<" ] = "
<<head->Data<<endl;
while (cur ->link != head)
{
cur = cur -> link;
cout<< "Data of node [ " <<l++<<" ] = "
<<cur->Data<<endl;
}
}

// Function for adding a new node at the beginning of the Circular Linked List
void adfirst_Cir(int m)
{
if( !head )
{
head = new nod;
head->Data = m;
last = head;
last -> link = head;
}
else
{
nod *temp = new nod;
temp -> Data = m;
temp -> link =head;
head = temp;
last -> link = head;
}
}
// Function for adding a new node at the end of the Circular Linked List
void addend_Cir(int n)
{
if( !last )
{
last = new nod;
last->Data = n;
head = last;
last -> link = head;
}
else
{
nod *temp = new nod;
temp -> Data = n;
last -> link = temp;
last = temp;
last -> link = head ;
}
}

// Function for adding a new node at any place of the Circular Linked List
void adany_Cir (int me)
{
nod *temp, *ptr ;
temp = new nod ;
temp -> Data = me ;
cur = head ;
while (cur -> Data < me )
{
ptr = cur ;
cur = cur -> link ;
}
ptr ->link=temp;
temp->link = cur ;
}

// Function for deleting a node from the beginning of the Circular Linked List
void defirst_Cir( )
{
cur = head;
head = head -> link;
delete cur;
last -> link = head;
}

// Function for deleting a node from the end of the Circular Linked List
void delast_Cir( )
{
cur = head ;
while (cur -> link != last )
cur = cur -> link;
delete last;
last = cur ;
last -> link = head;
}

// Function for deleting a node from any place of the Circular Linked List
void deany_Cir (int me )
{
assert(head -> Data != me);
assert(last -> Data != me);

nod *ptr;
cur = head ;
while (cur -> Data != me)
{
ptr = cur ;
cur = cur -> link ;
}
ptr -> link = cur -> link ;
delete cur ;
}

// Function for destroying the Circular Linked List


void destroy_Cir()
{
if ( ! head ) exist(1) ;
cur = head ;
while(cur -> link != head)
{
head = cur -> link;
delete cur;
cur = head;
}
cout<<" No linked List exist \n";
}
private:
int size;
nod *head, *cur, *last ;
};
SLL x(4);

main( )
{ x.create_Cir( ) ;
x.read_Cir();
clrscr( ) ;
char ch;
int m;
cout<<" \n SELECT A CHARACTER TO RUN ONE OF THE FOLLOWING: "<<endl;
cout<<" ______________________________________________ \n"<<endl;
cout<<" a: for the initialization of the Linked List "<<endl;
cout<<" b: for adding a new node at the beginning of the Linked List "<<endl;
cout<<" c: for adding a new node at the end of the Linked List "<<endl;
cout<<" d: for adding a new node at any place of the Linked List"<<endl;
cout<<" e: for deleting a node from the beginning of the Linked List"<<endl;
cout<<" f: for deleting a node from the end of the Linked List"<<endl;
cout<<" g: for deleting a node from any place of the Linked List"<<endl;
cout<<" h: for destroying the Linked List "<<endl;
cin>>ch;
switch(ch)
{
case 'a': {clrscr( );
x.initila_Cir();
x.write_Cir();
break;}

case 'b': {clrscr( );


cout<<" Enter the data for the new node ( First node) :";
cin>>m;
x.adfirst_Cir(m);
x.write_Cir();
break;}

case 'c': {clrscr( );


cout<<" Enter the data for the new node ( Last node) :";
cin>>m;
x.addend_Cir(m);
x.write_Cir();
break;}

case 'd': {clrscr( );


cout<<" Enter the data for the new node ( Any place ) \n"
<<" You have to select the new node within the data: " ;
cin>>m;
x.adany_Cir(m);
x.write_Cir();
break;}

case 'e': { clrscr( );


x.defirst_Cir();
x.write_Cir();
break;}

case 'f': {clrscr( );


x.delast_Cir();
x.write_Cir();
break;}

case 'g': {clrscr( );


cout<<" Enter the data for the node (Any place) \n"
<<" You have to select the node within the Linked List: " ;
cin>>m;
x.deany_Cir(m);
x.write_Cir();
break; }

case 'h': {clrscr( );


x.destroy_Cir();
x.write_Cir();
break;}

default: {clrscr( ) ;
exit(5);
}
}
}

‫ سوف تنشأ قائمة متصلة دورانية ويُطلب ِمنا إدخال‬،‫ومثل ما ذكرنا سابقا فعند تنفيذ ألبرنامج‬
.‫ألبيانات لكل عقدة ُمبتدا ِمن ألرأس ثم ألمرور بأل ُعقد ألباقية حتى أألخيرة‬
:‫بعد ذلك سوف تظھر لنا ألشاشة ألتالية‬
‫‪SELECT A CHARACTER TO RUN ONE OF THE FOLLOWING:‬‬
‫__________________________________________‬

‫‪a: for the initialization of the Linked List‬‬


‫‪b: for adding a new node at the beginning of the Linked List‬‬
‫‪c: for adding a new node at the end of the Linked List‬‬
‫‪d: for adding a new node at any place of the Linked List‬‬
‫‪e: for deleting a node from the beginning of the Linked List‬‬
‫‪f: for deleting a node from the end of the Linked List‬‬
‫‪g: for deleting a node from any place of the Linked List‬‬
‫‪h: for destroying the Linked List‬‬

‫حيث يتوجب علينا إختيار واحد من ألحروف ) من ‪ a‬إلى ‪ ( h‬وبخالف ذلك سوف نخرج من‬
‫ألبرنامج‪.‬‬
‫إن كل حرف أعاله يدل على عملية يتم تنفيذھا بإستخدام عبارة ‪ switch‬وألتي تتضمن ألحالة‬
‫‪ case‬ألمطلوبة وبدورھا فإن أالمر ‪ case‬سوف يعمل على تنفيذ كافة ألجمل في داخل ألكتلة‬
‫)‪ (block‬وألتي تكون من ضمنھا ألدالة ألرئيسية لتنفيذ ألعملية‪.‬‬

‫‪Double Linked List‬‬ ‫‪ .١١‬ألقا ئمة ألمتصلة ألمزدوجة‬


‫إن لكل عقدة في ألقائمة ألمتصلة ألمزدوجة ثالثة مكونات )‪ (components‬رئيسيات‪ .‬وعليه‬
‫فإن ألخطوة ألمھمة النشاء ألعقدة برمجيا ھي تعريف تركيب )‪ (struct‬وتكون صيغته على‬
‫ألنحو ألتالي‪:‬‬

‫{ ‪struct nod‬‬
‫; ‪int Data‬‬
‫; ‪nod *aft‬‬
‫; ‪nod *bef‬‬
‫;}‬
‫لكي نطبق ھذا ألتركيب‪ ،‬علينا أالعالن عن ألمؤشرات أالتية‪:‬‬

‫ألرأس )‪ (head‬وألذي يؤشر على ألعقدة أالولى من ألقائمة ألمتصلة‬ ‫‬


‫ألتيار )‪ (cura‬ألمؤشر ألالحق )‪ (after‬لكل عقدة‬ ‫‬
‫ألتيار )‪ (curb‬ألمؤشرألسابق )‪ (before‬لكل عقدة‬ ‫‬
‫أالخير )‪ (last‬ألمؤشر للعقدة أالخيرة‬ ‫‬

‫إن ألمتغيرات ألمناظرة لھا ھي‪:‬‬


‫ ‪*head‬‬
‫ ‪*cura‬‬
‫ ‪*curb‬‬
‫ ‪*last‬‬

‫وعلى ألترتيب‪.‬‬
‫‪Creating a Double linked List‬‬ ‫‪ .١٢‬إنشاء قائمة متصلة مزدوجة‬

‫إن ألفكرة ألرئيسية في إنشاء قائمة متصلة مزدوجة تكمن في وجود مؤشرين إثنين‪ ،‬يطلق على‬
‫أالول إسم ‪ after‬ويطلق على ألثاني إسم ‪ before‬بإالضافة إلى ألمؤشرات ألرأس ‪ ،‬ألتيار‬
‫وأالخير‪ .‬يمكن تنفيذ ذلك وذلك بإستخدام ألمؤثر جديد )‪ (new‬وألذي بدوره يوفر موقع تخزين‬
‫ديناميكي‪.‬‬
‫للقائمة ألمتصلة ألمزدوجة فوائد عديدة منھا‪:‬‬

‫إدخال ألبيانات يمكن أن يتم من أألخير إلى ألرأس‬


‫ألتجول في ألقائمة يمكن أن يتم من أألخير إلى ألرأس‬
‫سھولة زيارة أية عقدة في ألقائمة‬
‫سھولة إضافة أية عقدة إلى ألقائمة‬
‫سھولة حذف أية عقدة من ألقائمة‬

‫وعليه‪ ،‬النشاء قائمة متصلة مزدوجة نتبع ألخطوات ألبرمجية أالتية‪:‬‬


‫‪// Program Chr1_03.cpp‬‬
‫>‪# include<iostream.h‬‬

‫{‪struct nod‬‬
‫; ‪int Data‬‬
‫; ‪nod * after‬‬
‫; ‪nod *before‬‬
‫;}‬

‫; ‪typedef nod * ptr‬‬


‫;‪ptr head, cura, curb, last‬‬

‫) ( ‪void create_D‬‬
‫{‬
‫; ‪head = new nod‬‬
‫; ‪head -> before = NULL‬‬
‫; ‪head -> after = NULL‬‬
‫; ‪cura = head‬‬
‫; ‪curb = head‬‬
‫) ‪for (int i = 1 ; i <= 4 ; i++‬‬
‫{‬
‫; ‪cura -> after = new nod‬‬
‫; ‪cura = cura -> after‬‬
‫;‪cura -> before = curb‬‬
‫; ‪curb = curb -> after‬‬
‫}‬
‫; ‪last = cura‬‬
‫; ‪last -> after = NULL‬‬ ‫}‬
‫) (‪main‬‬
‫} ; ) ( ‪{ create_D‬‬

‫في ھذا ألبرنامج تم إنشاء قائمة متصلة مزدوجة مكونة من خمسة عقد ويمكن توضيح ذلك‪:‬‬

‫ألعبارة‬

‫; ‪head = new nod‬‬

‫من أجل إنشاء عقدة ألرأس وألتي يمكن تمثيلھا بألشكل ‪٤٥ -١‬‬

‫‪head‬‬

‫‪*head‬‬

‫ألشكل ‪ ٤٥ -١‬عقدة ألرأس‬

‫أما ألعبارات‬
‫; ‪head -> before = NULL‬‬
‫; ‪head -> after = NULL‬‬

‫فھي تعمل على جعل ألمؤشر ألسابق وألمؤشر ألالحق للعقدة بألتأشير على ألفراغ‬
‫)‪.(NULL‬وعليه تكون ألعقدة كما في ألشكل ‪٤٦ – ١‬‬

‫‪head‬‬

‫‪before‬‬ ‫‪after‬‬

‫ألشكل ‪ ٤٦ -١‬عقدة ألرأس‬

‫أما ألعبارات‬
‫; ‪cura = head‬‬
‫; ‪curb = head‬‬

‫فھي تعمل على نسخ ألعقدة ألرأس إلى ألعقدة ألتيار ألالحق وألتيار ألسابق‪ ،‬يمكن توضيح ذلك‬
‫بالشكل ‪. ٤٦ -١‬‬
‫‪head, cura, curb‬‬

‫ألشكل ‪ ٤٦ -١‬ألعقدة ‪head, cura, curb‬‬

‫أما جملة ألتكرار ‪ for‬فھي تعمل على إنشاء بقية ألعقد حيث أن ألعبارة‪:‬‬

‫; ‪cura -> after = new nod‬‬


‫تعمل على إنشاء عقدة تلي ألعقدة ألتيار‪ ،‬أما ألعبارة‪:‬‬
‫; ‪cura = cura -> after‬‬

‫فھي لنقل أالسم تيار )‪ (cura‬إلى ألعقدة ألتالية وألتي تم إنشاؤھا وكما ھو موضح بألشكل ‪47 -١‬‬

‫‪head‬‬ ‫‪cura‬‬

‫‪*head‬‬ ‫‪*cura‬‬

‫ألشكل ‪ 47 -١‬نقل أالسم ‪ cura‬إلى ألعقدة ألتالية‬

‫أما ألعبارات‪:‬‬
‫;‪cura -> before = curb‬‬
‫; ‪curb = curb -> after‬‬
‫فھي تعمل على ربط ألعقدة ألجديدة )‪ (cura‬بألعقدة ألسابقة )‪ (curb‬ثم تسمية ألعقدة ألجديدة‬
‫بأالسم )‪ (curb‬وكما ھو موضح في ألشكل ‪٤٨ - ١‬‬

‫‪head‬‬ ‫‪cura, curb‬‬

‫ألشكل ‪ 48 -١‬نقل أالسم ‪ curb‬إلى ألعقدة ألتالية‬


‫بعد سلسلة من ألتكرارات نحصل على ألقائمة ألمتصلة ألمزدوجة‪ ،‬وكما في ألشكل ‪49 -١‬‬

‫‪head‬‬ ‫‪cura‬‬

‫‪*head‬‬ ‫‪*cura‬‬

‫ألشكل ‪ ٤٩ -١‬قائمة متصلة مزدوجة‬


‫من ألناحية أالخرى فإن ألبرنامج سوف يمنح ألعقدة أالخيرة إسم أالخير )‪ (last‬وألجملة ألخاصة‬
‫بذلك ھي‪:‬‬

‫; ‪last = cura‬‬

‫وبما أن ألعقدة أالخيرة تؤشر على فراغ )‪ (NULL‬فإن ألجملة ألخاصة بذلك ھي‪:‬‬

‫; ‪last -> after = NULL‬‬

‫إن ألصيغة ألنھائية للقائمة ألمتصلة ألمزدوجة تكون كما في ألشكل ‪٥٠ -١‬‬

‫‪head‬‬ ‫‪last‬‬

‫‪*head‬‬ ‫‪*last‬‬
‫ألشكل ‪ ٥٠ -١‬قائمة متصلة مفردة‬

‫‪Inserting data‬‬ ‫‪ .١٣‬إدخال ألبيانات‬

‫ھنا نوضح كيفية إدخال ألبيانات لكل عقدة من ألعقد‪ ،‬لقد تم تخصيص دالة لقراءة ألبيانات من‬
‫لوحة ألمفاتيح ثم وضع كل قيمة في ألعقدة ألمناسبة‪.‬‬
‫ألدالة ستكون على ألنحو أالتي‪:‬‬
‫) ( ‪void read_D‬‬
‫; " ‪{ cout<< "Enter the value for the head :‬‬
‫; ‪cin>> head -> Data‬‬
‫; ‪cura = head‬‬
‫)‪while( cura -> after‬‬
‫{‬
‫; " ‪cout<< " Enter the values of the items :‬‬
‫; ‪cura = cura -> after‬‬
‫; ‪cin>> cura -> Data‬‬
‫}‬
‫}‬

‫تضمن ألبرنامج أعاله قراءة‪ ،‬من لوحة ألمفاتيح‪ ،‬ألقيمة ألخاصة بألرأس وذلك بإستخدام ألعبارة‬

‫; ‪cin>> head -> Data‬‬

‫كما تم إستخدام ألعبارة‬


‫)‪while( cur->after‬‬
‫وذلك للمرور بكافة ألعقد وتخصيص ألقيمة ألبيانية لتلك ألعقد‪.‬‬
‫سوف ينتھي تأثير ألصيغة ألتكرارية عندما يتحقق ألشرط‪:‬‬

‫‪cur -> after == NULL‬‬

‫إن صيغة ألتنفيذ ستكون كما يلي‪:‬‬

‫) (‪main‬‬
‫{‬
‫; ) ( ‪Create_D‬‬
‫; ) ( ‪Read_D‬‬
‫}‬
‫يطلب منا ألبرنامج إدخال قيم لكل من‪:‬‬

‫ ألرإس‬
‫ أربعة عقد متبقية تشمل كذلك أالخير‬

‫مثال ذلك عند إدخال ألقيم‪:‬‬

‫ ‪١‬‬
‫ ‪٩ ،٦ ،٥ ،٢‬‬

‫فإن ألقائمة ألمتصلة ستأخذ ألشكل ‪ ١٠ -١‬وكما ياي‪:‬‬

‫‪head‬‬ ‫‪last‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪6‬‬ ‫‪9‬‬


‫‪*head‬‬ ‫‪*last‬‬
‫ألشكل ‪ 51 -١‬قائمة متصلة مزدوجة‬

‫‪Traversing a Double Linked List‬‬ ‫‪ .١٤‬التجول في قائمة متصلة مزدوجة‬

‫نعني بألتجول في قائمة متصلة ھو زيارة كل عقدة من عقد ألقائمة مبتدئين بألرأس حتى ألعقدة‬
‫أالخيرة‪ .‬ألتركيب ألخاص للدالة يكون على ألنحو أالتي‪:‬‬
‫) (‪void write_D‬‬
‫{‬
‫;‪int l = 0‬‬
‫; ‪cura = head‬‬
‫)‪while (cura‬‬
‫{‬
‫" = ] "<<‪cout<< "Data of node [ " <<l++‬‬
‫;‪<<cura->Data<<endl‬‬
‫;‪cura = cura -> after‬‬
‫}‬
‫}‬
‫إضافة ألدالة إلى ألبرنامج ألسابق مع إجراء أالضافة ألى ألصيغة ألتنفيذية وكما يلي‪:‬‬

‫) ( ‪main‬‬
‫{‬
‫; ) (‪Create_D‬‬
‫; ) (‪Read_D‬‬
‫; ) ( ‪clrscr‬‬
‫; ) (‪write_D‬‬
‫}‬

‫عند ألتنفيذ‪ ،‬نحصل على ألنتائج أالتية‪:‬‬

‫= ] ‪Data of node [ 0‬‬ ‫‪1‬‬


‫= ] ‪Data of node [ 1‬‬ ‫‪2‬‬
‫= ] ‪Data of node [ 2‬‬ ‫‪5‬‬
‫= ] ‪Data of node [ 3‬‬ ‫‪6‬‬
‫= ] ‪Data of node [ 4‬‬ ‫‪9‬‬

‫مالحظة‪:‬‬
‫تم إستخدام ألدالة ‪ clrscr‬وذلك الزالة ألنص من ألنافذة ووضع ألمؤشر عند ألبداية‪.‬‬
‫بكل تأكيد سوف نضمن برنامجنا بألملف ألرأسي ‪ conio.h‬ألذي يحوي ألدالة ‪. clrscr‬‬

‫وكما ذكرنا سابقا فإن للقائمة ألمتصلة ألمزدوجة سھولة ألتجول في كال أالتجاھين‪:‬‬
‫‪ -‬من ألرأس إلى أالخير‬
‫‪ -‬من أالخير إلى ألرأس‬

‫إن ألدالة أعاله سھلة عملية ألتجول من ألرأس وحتى أالخير‪ ،‬أما إذا أردنا ألتجول من أالخير إلى‬
‫ألرأس فألدالة أالتية تقدم لنا ھذه ألخدمة‪:‬‬
void write_DR( )
{
cout<<"\n writing the data of the Circular Linked List in reverse order: \n\n";
int l = 4;
curb = last ;
while (curb)
{
cout<< "Data of node [ " <<l--<<" ] = "
<<curb->Data<<endl;
curb = curb -> before;
}
}

:‫ نحصل على ألنتائج أالتية‬،‫عند ألتنفيذ‬

Data of node [ ٤ ] = ٩
Data of node [ ٣ ] = ٦
Data of node [ 2 ] = 5
Data of node [ ١ ] = ٢
Data of node [ ٠ ] = ١

‫ ألعمليات أالساسية على ألقائمة ألمتصلة ألزدوجة‬.١٥


Basic Operations on Double Linked List

:‫يتضمن ھذا ألجزء من ألفصل ألمواضيع أالتية‬

‫ عقدة في موقع معين من ألقائمة ألمتصلة‬insert ‫ حشر‬


‫ عقدة من موقع معين في ألقائمة ألمتصلة‬delete ‫ حذف‬

:‫حشر عقدة‬
:‫لحشر عقدة جديدة في بداية ألقائمة ألمتصلة ألمزدوجة نستخدم ألدالة أالتية‬

void adfirst_D(int m)
{
if(!head)
{
head = new nod;
head->Data = m;
head -> after = NULL;
last = head;
‫;‪last -> before = NULL‬‬
‫}‬
‫‪else‬‬
‫{‬
‫;‪nod *temp = new nod‬‬
‫;‪temp -> Data = m‬‬
‫;‪temp -> after =head‬‬
‫; ‪head -> before = temp‬‬
‫;‪temp -> before = NULL‬‬
‫;‪head = temp‬‬
‫}‬
‫}‬

‫يفترض ألجزء أالول من ألدالة عدم إحتواء ألقائمة ألمتصلة ألمزدوجة على أية عقدة وعليه فإن‬
‫ألعقدة ألجديدة ستكون ھي ألعقدة ألرأس وھي ألعقدة أالخيرة في نفس ألوقت‪ .‬في حين إن لم تكن‬
‫ألقائمة ألمتصلة ألمزدوجة خالية فإننا نستطيع إضافة ألعقدة ألجديدة في ألموقع ألمناسب‪.‬‬
‫ألشكل ‪ ٥٢ -١‬يوضح ألعبارتين من أالمر ‪ else‬وھي‪:‬‬

‫;‪nod *temp = new nod‬‬


‫;‪temp -> Data = m‬‬

‫‪head‬‬ ‫‪last‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪6‬‬ ‫‪9‬‬

‫‪temp‬‬

‫‪m‬‬

‫‪*temp‬‬
‫ألشكل ‪ 52 -١‬إضافة عقدة جديدة لقائمة متصلة مزدوجة‬
‫أما ألعبارات‪:‬‬

‫;‪temp -> after =head‬‬


‫; ‪head -> before = temp‬‬
‫;‪temp -> before = NULL‬‬
‫;‪head = temp‬‬

‫فھي تعمل على ربط ألعقدة ألجديدة بألعقدة ألرأس ثم يتم إطالق إسم ألرأس على ألعقدة ألجديدة‪.‬‬
‫ألشكل ‪ 53 -١‬يوضح ذلك‬
‫‪last‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪6‬‬ ‫‪9‬‬

‫‪head‬‬

‫‪m‬‬

‫ألشكل ‪ ٥٣ -١‬ألقائمة ألمتصلة ألمزدوجة ألجديدة‬

‫يمكن إضافة ھذه ألدالة ليكون ألجزء ألتنفيذي للبرنامج على ألنحو أالتي‪:‬‬

‫) (‪main‬‬
‫; ) ( ‪{ create_D‬‬
‫;) ( ‪Read_D‬‬
‫;) ( ‪clrscr‬‬
‫;) ( ‪write_D‬‬
‫;"‪cout<<" Enter the Data for the new first node :‬‬
‫;‪cin>>m‬‬
‫;)‪Adfirst_D(m‬‬
‫;) ( ‪clrscr‬‬
‫;) ( ‪write_D‬‬ ‫}‬

‫فإذا كانت قيمة ألبيانات للعقدة ألجديدة ھي ‪ m = 0‬فإن مخرجات ألبرنامج تكون على ألنحو‬
‫أالتي‪:‬‬

‫‪Data of node [ 0 ] = 0‬‬


‫‪Data of node [ 1 ] = 1‬‬
‫‪Data of node [ 2 ] = 2‬‬
‫‪Data of node [ 3 ] = 5‬‬
‫‪Data of node [ 4 ] = 6‬‬
‫‪Data of node [ 5 ] = 9‬‬

‫أما عند إضافة عقدة جديدة في نھاية ألقائمة ألمتصلة ألمزدوجة فيمكن تطبيق ألدالة أالتية‪:‬‬

‫)‪void addend_D(int n‬‬


‫{‬
‫) ‪if( !last‬‬
‫{‬
‫;‪last = new nod‬‬
‫;‪last->Data = n‬‬
‫; ‪last -> after = NULL‬‬
‫; ‪last -> before = NULL‬‬
‫; ‪head = last‬‬
‫}‬
‫‪else‬‬
‫{‬
‫; ‪nod *temp = new nod‬‬
‫; ‪temp -> Data = n‬‬
‫; ‪last -> after = temp‬‬
‫; ‪temp -> before = last‬‬
‫; ‪last = temp‬‬
‫; ‪last -> after = NULL‬‬
‫}‬
‫}‬

‫وكما ذكرنا سابقا وبإفتراض بأن ألجزء أالول من ألدالة يتعامل مع قائمة متصلة مزدوجة ال‬
‫تحتوي على أية عقدة وعليه فإن ألعقدة ألجديدة ستكون ھي ألعقدةأالخيرة وھي ألعقدة ألرأس في‬
‫نفس ألوقت‪ .‬في حين إن لم تكن ألقائمة ألمتصلة ألمزدوجة خالية فإننا نستطيع إضافة ألعقدة‬
‫ألجديدة‪.‬‬
‫ألشكل ‪ 54 -١‬يوضح ألعبارتين من أالمر ‪ else‬وھي‪:‬‬

‫;‪nod *temp = new nod‬‬


‫;‪temp -> Data = n‬‬

‫‪head‬‬ ‫‪last‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪6‬‬ ‫‪9‬‬

‫‪temp‬‬

‫‪n‬‬
‫‪*temp‬‬
‫ألشكل ‪ 54 -١‬إضافة عقدة جديدة لقائمة متصلة مزدوجة‬

‫أما ألعبارات‪:‬‬
‫; ‪last -> after = temp‬‬
‫; ‪temp -> before = last‬‬
‫; ‪last = temp‬‬
‫; ‪last -> after = NULL‬‬

‫فھي تعمل على ربط ألعقدة أالخيرة بألعقدة ألجديدة ثم يتم إطالق إسم أالخيرعلى ألعقدة ألجديدة‬
‫وألعبارة أالخيرة تجعل من مؤشر ألعقدة أالخيرة يؤشر على ألفراغ‪.‬‬
‫ألشكل ‪ ١٤ -١‬يوضح ذلك‬

‫‪head‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪6‬‬ ‫‪9‬‬

‫‪last‬‬

‫‪n‬‬

‫ألشكل ‪ ١٤ -١‬ألقائمة ألمتصلة ألمزدوجة ألجديدة‬

‫يمكن إضافة ھذه ألدالة ليكون ألجزء ألتنفيذي للبرنامج على ألنحو أالتي‪:‬‬

‫) (‪main‬‬
‫; ) ( ‪{ create_D‬‬
‫;) ( ‪read_D‬‬
‫;) ( ‪clrscr‬‬
‫;) ( ‪write_D‬‬
‫;"‪cout<<" Enter the Data for the new end node :‬‬
‫;‪cin>>n‬‬
‫;)‪addend_D(n‬‬
‫;) ( ‪clrscr‬‬
‫;) ( ‪write_D‬‬ ‫}‬

‫فإذا كانت قيمة ألبيانات للعقدة ألجديدة ھي ‪ n = 10‬فإن مخرجات ألبرنامج تكون على ألنحو‬
‫أالتي‪:‬‬
‫‪Data of node [ 0 ] = 1‬‬
‫‪Data of node [ 1 ] = 2‬‬
‫‪Data of node [ 2 ] = 5‬‬
‫‪Data of node [ 3 ] = 6‬‬
‫‪Data of node [ 4 ] = 9‬‬
‫‪Data of node [ 5 ] = 10‬‬
‫أما عند إضافة عقدة جديدة في مكان ما من ألقائمة ألمتصلة ألمزدوجة فيمكن تطبيق ألدالة أالتية‪:‬‬

‫)‪void adany_D (int me‬‬


‫{‬
‫; ‪nod *temp, *ptr1‬‬
‫; ‪temp = new nod‬‬
‫; ‪temp -> Data = me‬‬
‫; ‪cura = head‬‬
‫) ‪while (cura -> Data < me‬‬
‫{‬
‫; ‪ptr1 = cura‬‬
‫; ‪cura = cura -> after‬‬
‫}‬
‫;‪ptr1 -> after=temp‬‬
‫; ‪temp-> after = cura‬‬
‫}‬

‫ألدالة أعاله تعمل على تحديد موقع ألعقدة ألجديدة وذلك بمعرفة ألعقدة ألتي قبلھا ‪ ptr1‬وألعقدة‬
‫ألتي بعدھا ‪ ، cura‬ويتم تحديد ذلك بإستخدام ألصيغة ‪ while‬حيث تحدد قيمة ألعقدة ألسابقة‬
‫بألعبارة‬
‫; ‪ptr1 = cura‬‬

‫وتحدد ألقيمة ألتالية بألعبارة‬


‫; ‪cura = cura -> after‬‬
‫مالحظة‪:‬‬
‫ألدالة أعاله صحيحة عندما تكون ألبيانات مرتبة ترتيبا تصاعديا‪.‬‬

‫ألشكل ‪ 56 -١‬يوضح إنشاء ألعقدة ألجديدة ) ‪ (*temp‬ثم إجراء عملية ربط بين أألعقدة ألجديدة‬
‫)‪ (temp‬وألعقدتين ألسابقة وألالحقة لھا وكما يلي‪:‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪6‬‬ ‫‪9‬‬

‫‪n‬‬

‫ألشكل ‪ ٥٦ -١‬إضافة عقدة جديدة إلى ألقائمة ألمتصلة ألمزدوجة‬


‫حذف عقدة‪:‬‬

‫إن عملية حذف عقدة من قائمة متصلة مزدوجة تشبه عملية حذف عقدة من قائمة متصلة مفردة‪.‬‬
‫إن ألحذف سيكون من ألمواقع أالتية‪:‬‬

‫ بداية ألقائمة ألمتصلة ألمزدوجة‬


‫ أية موقع من ألقائمة ألمتصلة ألمزدوجة‬
‫ نھاية ألقائمة ألمتصلة ألمزدوجة‬

‫إن أالختالف ھو في ألتعامل مع ألمؤشرات ألسابق وألالحق‪.‬‬


‫فلحذف عقدة من بداية ألقائمة ألمتصلة ألمزدوجة نستخدم ألدالة أالتية‪:‬‬

‫) (‪void defirst_D‬‬
‫{‬
‫;‪cura = head‬‬
‫;‪head = head -> after‬‬
‫;‪delete cura‬‬
‫; ‪head -> before = NULL‬‬
‫}‬
‫عند تطبيق ھذه ألدالة لحذف ألعقدة ألرأس من ألقائمة ألمتصلة ألمزدوجة فإن أولى ألخطوات ھي‬
‫تسمية ألعقدة ألرأس بألعقدة تيار )‪:(cura‬‬
‫; ‪cura = head‬‬

‫أما ألعبارة‬
‫;‪head = head -> after‬‬

‫فتعمل على نقل ألمؤشر ‪ head‬إلى ألعقدة ألتالية ‪ ،‬وألخطوة ألتالية تعمل على حذف ألعقدة‬
‫‪cura‬‬
‫;‪delete cura‬‬

‫وأخيرا نعمل على جعل ألمؤشر ‪ before‬للعقدة ألرأس يؤشر على ألفراغ‬

‫; ‪head -> before = NULL‬‬

‫ألصيغة ألنھائية للقائمة ألمتصلة ألمزدوجة ستكون على ألنحو أالتي‪:‬‬

‫‪head‬‬ ‫‪last‬‬

‫‪٢‬‬ ‫‪5‬‬ ‫‪6‬‬ ‫‪9‬‬

‫ألشكل ‪ 57 -١‬ألقائمة ألمتصلة ألمزدوجة بعد ألحذف‬


‫وللحصول على ألبيانات يمكن تطبيق ألبرنامج أالتي‬

‫) (‪main‬‬
‫; ) (‪{ create_D‬‬
‫;) (‪read_D‬‬
‫;) (‪defirst_D‬‬
‫;) (‪clrscr‬‬
‫;) (‪write_D‬‬ ‫}‬

‫ومخرجات ألبرنامج تكون على ألنحو أالتي‪:‬‬

‫‪Data of node [ 0 ] = 2‬‬


‫‪Data of node [ 1 ] = 5‬‬
‫‪Data of node [ 2 ] = 6‬‬
‫‪Data of node [ 3 ] = 9‬‬

‫لحذف عقدة من نھاية ألقائمة ألمتصلة ألمزدوجة نستخدم ألدالة أالتية‪:‬‬

‫) (‪void delast_D‬‬
‫{‬
‫; ‪curb = last‬‬
‫; ‪last = last -> before‬‬
‫;‪delete curb‬‬
‫;‪last -> after = NULL‬‬
‫}‬

‫فألعبارة أالولى‬
‫; ‪curb = last‬‬

‫تعمل على تسمية ألعقدة ألرأس بألعقدة ألتيار )‪ (curb‬وأما ألعبارة ألثانية فتعمل على تسمية‬
‫ألعقدة ألسابقة للعقدة أالخيرة بألعقدة أالخيرة كما في ألشكل ‪٥٨ -١‬‬

‫‪head‬‬ ‫‪last‬‬ ‫‪curb‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪6‬‬ ‫‪9‬‬

‫ألشكل ‪ ٥٨ -١‬ألمؤشر ‪curb‬‬

‫نستطيع أالن وبسھولة تنفيذ ألجملة‪:‬‬


‫;‪delete curb‬‬
‫وذلك لحذف ألعقدة أالخيرة‪.‬‬

‫ألشكل ‪ ٥٩ -١‬يبين ألقائمة ألمتصلة ألجديدة‬

‫‪head‬‬ ‫‪last‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪6‬‬

‫ألشكل ‪ ٥٩ -١‬ألقائمة ألمتصلة ألمزدوجة بعد ألحذف‬

‫للحصول على ألقائمة ألمتصلة أعاله يمكن تنفيذ ألبرنامج أالتي‪:‬‬


‫) (‪main‬‬
‫; ) (‪{ create_D‬‬
‫;) (‪Read_D‬‬
‫;) (‪Delast_D‬‬
‫;) (‪clrscr‬‬
‫;) (‪write_D‬‬ ‫}‬

‫مخرجات ألبرنامج تكون على ألنحو أالتي‪:‬‬

‫‪Data of node [ 0 ] = 1‬‬


‫‪Data of node [ 1 ] = 2‬‬
‫‪Data of node [ 2 ] = 5‬‬
‫‪Data of node [ 3 ] = 6‬‬

‫لحذف عقدة من أية موقع في ألقائمة ألمتصلة ألمزدوجة ) بإستثناء ألعقدة أالولى ‪head‬‬
‫وألعقدة أالخيرة ‪ ( last‬نستخدم ألدالة أالتية‪:‬‬

‫) ‪void deany_D (int me‬‬


‫{‬
‫;)‪assert(head -> Data != me‬‬
‫;)‪assert(last -> Data != me‬‬

‫;‪nod *ptr1‬‬
‫; ‪cura = head‬‬
‫)‪while (cura -> Data != me‬‬
‫{‬
‫; ‪ptr1 = cura‬‬
‫; ‪cura = cura -> after‬‬
‫}‬
‫; ‪curb = cura -> after‬‬
‫; ‪ptr1 -> after = curb‬‬
‫; ‪curb -> before = ptr1‬‬
‫; ‪delete cura‬‬
‫}‬

‫وكما ذكرنا فإن إستخدام ألدالة ال ينطبق على حذف ألعقدة أالولى أو ألعقدة أالخيرة فلقد تم‬
‫إستخدام ألدالة ‪ assert‬ألستثناء ألعقدتين أالولى وأالخيرة وكما يلي‪:‬‬

‫;)‪assert(head -> Data != me‬‬


‫;)‪assert(last -> Data != me‬‬

‫فإذا تم إدخال ألقيمة ‪ ١‬وھي ألبيانات ألموجودة في عقدة ألرأس ‪ head‬أو ألقيمة ‪ ٩‬وھي‬
‫ألبيانات ألموجودة في ألعقدة أالخيرة ‪ last‬فسوف تظھر ألصيغة أالتية‪:‬‬

‫‪Assertion failed: head -> Data != me, file filename.CPP, line 5,‬‬

‫أو ألصيغة‬

‫‪Assertion failed: last -> Data != me, file filename.CPP, line 6,‬‬

‫أما إذا كانت ألقيمة غير ذلك فإن ألبرنامج سوف يعمل على أالعالن عن عقدة مؤشرھا ‪ptr1‬‬
‫لتكون ألعقدة ألسابقة للعقدة ألمراد حذفھا‪ ،‬وأالعالن ھو‬

‫; ‪nod *ptr1‬‬

‫ويخصص ألمؤشر ‪ cura‬للعقدة ألمراد حذفھا‬


‫وللوصول إلى ألعقد ألمحددة نستخدم جملة ‪ while‬وعلى ألنحو أالتي‪:‬‬

‫)‪while (cur -> Data != me‬‬


‫{‬
‫; ‪ptr1 = cura‬‬
‫; ‪cura = cura -> after‬‬
‫}‬

‫فإذا إفترضنا بأن بيانلت ألعقدة ألمراد حذفھا تساوي ‪ ) ٥‬أي أن ‪ ( me = 5‬فإن ألشكل سيكون‬
‫على ألنحو أالتي‪:‬‬

‫‪head‬‬ ‫‪ptr1‬‬ ‫‪cura‬‬ ‫‪curb‬‬ ‫‪last‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪6‬‬ ‫‪9‬‬

‫ألشكل ‪ 60 -١‬ألمؤشرات ‪ptr1, cura and curb‬‬


‫تبدأ عملية ألحذف وذلك بإستخدام ألعبارات أالتية‪:‬‬
‫; ‪curb = cura -> after‬‬
‫; ‪ptr1 -> after = curb‬‬
‫; ‪curb -> before = ptr1‬‬
‫; ‪delete cura‬‬

‫فتكون ألقائمة ألمتصلة ألجديدة كما في ألشكل ‪٦١ -١‬‬

‫‪head‬‬ ‫‪last‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪٦‬‬ ‫‪٩‬‬

‫ألشكل ‪ ٦١ -١‬ألقائمة ألمتصلة ألجديدة‬

‫للحصول على ألقائمة ألمتصلة أعاله يمكن تنفيذ ألبرنامج أالتي‪:‬‬


‫) (‪main‬‬
‫; ) (‪{ create_D‬‬
‫;) (‪read_D‬‬
‫;)‪deany_D(5‬‬
‫;) (‪clrscr‬‬
‫;) (‪write_D‬‬ ‫}‬

‫مخرجات ألبرنامج تكون على ألنحو أالتي‪:‬‬

‫‪Data of node [ 0 ] = 1‬‬


‫‪Data of node [ 1 ] = 2‬‬
‫‪Data of node [ 2 ] = 6‬‬
‫‪Data of node [ 3 ] = 9‬‬

‫مالحظة‪:‬‬

‫‪ -‬لحذف عقدة من أية موقع في ألقائمة ألمتصلة يجب أن تحمل نفس قيمة ألبيان‪:‬ات‬
‫وألتي تساوي قيمة ألمتغير ‪ ،me‬أي يجب أن تكون ألعق‪:‬دة ألم‪:‬راد ح‪:‬ذفھا داخ‪:‬ل‬
‫ألقائمة ألمتصلة‪.‬‬
‫‪ -‬البتداء قائمة متصلة يمك‪:‬ن إس‪:‬تخدام ألدال‪:‬ة ألمعرف‪:‬ة بإس‪:‬م ‪ initila‬وألمس‪:‬تخدمة‬
‫في ألبرنامج ألعام ‪program Chr1-02‬‬
‫‪ -‬كذلك ألحال بألنسبة للدالة ‪.destroy‬‬
‫‪The General Computer Program‬‬ ‫‪ .١٦‬ألبرنامج ألعام‬

‫ألبرنامج أألتي ھو برنامج عام وشامل لكافة ألعمليات ألتي يمكن تنفيذھا على ألقائمة ألمتصلة‬
‫ألمزدوجة‪ ،‬حيث يشمل ألبرنامج على ما يلي‪:‬‬

‫إنشاء ألقائمة ألمتصلة ألمزدوجة‬ ‫‬


‫إدخال ألبيانات لكل عقدة‬ ‫‬
‫ألتجول في ألقائمة ألمتصلة ألمزدوجة‬ ‫‬
‫إبتداء ألقائمة ألمتصلة ألمزدوجة‬ ‫‬
‫إضافة عقدة جديدة عند ألرأس‬ ‫‬
‫إضافة عقدة جديدة بعد ألعقدة أالخيرة‬ ‫‬
‫إضافة عقدة جديدة في أية مكان من ألقائمة ألمزدوجة‬ ‫‬
‫حذف ألعقدة أالولى من ألقائمة ألمتصلة ألمزدوجة‬ ‫‬
‫حذف ألعقدة أالخيرة من ألقائمة ألمتصلة ألمزدوجة‬ ‫‬
‫حذف أية عقدة من ألقائمة ألمتصلة ألمزدوجة‬ ‫‬
‫تدمير ألقائمة ألمتصلة ألمزدوجة‬ ‫‬

‫‪// Program Chr١_٠٢.cpp‬‬

‫>‪# include<iostream.h‬‬
‫>‪# include<conio.h‬‬
‫>‪# include<stdlib.h‬‬
‫>‪# include<assert.h‬‬

‫{ ‪class nod‬‬
‫‪public:‬‬
‫; ‪int Data‬‬
‫; ‪nod *after‬‬
‫; ‪nod *before‬‬
‫;}‬

‫{ ‪class SLL‬‬
‫‪public:‬‬
‫} ;‪SLL(int s){size = s‬‬

‫‪// Function for the initialization of the Double Linked List‬‬


‫) (‪void initila_Cir‬‬
‫{‬
‫} ; ‪head = last = NULL‬‬

‫‪// Function for creating the Double Linked List‬‬


void create_D ( )
{
head = new nod ;
head -> before = NULL ;
head -> after = NULL ;
cura = head ;
curb = head ;
for (int i = 1 ; i <= size ; i++ )
{
cura -> after = new nod ;
cura = cura -> after ;
cura -> before = curb;
curb = curb -> after ;
}
last = cura ;
last -> after = NULL ;
}

// Function for inserting data for each node in the Double Linked List
void read_D ( )
{
cout<< "Enter the value for the head : " ;
cin>> head -> Data ;
cura = head ;
while( cura -> after)
{
cout<< " Enter the values of the items : " ;
cura = cura -> after ;
cin>> cura -> Data ;
}
}

// Function for traversing (forward) the Double Linked List


void write_D( )
{
int l = 0;
cura = head ;
while (cura)
{
cout<< "Data of node [ " <<l++<<" ] = "
<<cura->Data<<endl;
cura = cura -> after;
}
}

// Function for traversing (backward) the Double Linked List


void write_DR( )
{
cout<<"\n writing the data of the Double Linked List in reverse order: \n\n";
int l = size;
curb = last ;
while (curb)
{
cout<< "Data of node [ " <<l--<<" ] = "
<<curb->Data<<endl;
curb = curb -> before;
}
}

// Function for adding a new node at the beginning of the Double Linked List
void adfirst_D(int m)
{
if(!head)
{
head = new nod;
head->Data = m;
head -> after = NULL;
last = head;
last -> before = NULL;
}
else
{
nod *temp = new nod;
temp -> Data = m;
temp -> after =head;
head -> before = temp ;
temp -> before = NULL;
head = temp;
}
}

// Function for adding a new node at the end of the Double Linked List
void addend_D(int n)
{
if( !last )
{
last = new nod;
last->Data = n;
last -> after = NULL ;
last -> before = NULL ;
head = last ;
}
else
{
nod *temp = new nod ;
temp -> Data = n ;
last -> after = temp ;
temp -> before = last ;
last = temp ;
last -> after = NULL ;
}
}

// Function for adding a new node at any place of the Double Linked List
void adany_D (int me)
{
nod *temp, *ptr1 ;
temp = new nod ;
temp -> Data = me ;
cura = head ;
while (cura -> Data < me )
{
ptr1 = cura ;
cura = cura -> after ;
}
ptr1 -> after=temp;
temp-> after = cura ;
}

// Function for deleting a node from the beginning of the Double Linked List
void defirst_D( )
{
cura = head;
head = head -> after;
delete cura;
head -> before = NULL ;
}
// Function for deleting a node from the end of the Double Linked List
void delast_D( )
{
curb = last ;
last = last -> before ;
delete curb;
last -> after = NULL;
}

// Function for deleting a node from any place of the Double Linked List
void deany_D(int me )
{
assert(head -> Data != me);
assert(last -> Data != me);
nod *ptr1;
cura = head ;
while (cura -> Data != me)
{
ptr1 = cura ;
cura = cura -> after ;
}
curb = cura -> after ;
ptr1 -> after = curb ;
curb -> before = ptr1 ;
delete cura ;
}

// Function for destroying the Double Linked List


void destroy_D()
{
if ( ! head ) exit(1) ;
cura = head ;
while(cura)
{
head = cura -> after;
delete cura;
cura = head;
}
cout<<" No linked List exist \n";
}
// Function for initializing the Double Linked List
void initila_D()
{
head = last = NULL ; }

private:
int size;
nod *head, *cura, *curb, *last ;
};
SLL x(4);

main( )
{ x.create_D( ) ;
x.read_D();
clrscr( ) ;
char ch;
int m;
cout<<" \n SELECT A CHARACTER TO RUN ONE OF THE FOLLOWING: "<<endl;
cout<<" ______________________________________________ \n"<<endl;
cout<<" a: for the initialization of the Linked List "<<endl;
cout<<" b: for adding a new node at the beginning of the Linked List "<<endl;
cout<<" c: for adding a new node at the end of the Linked List "<<endl;
cout<<" d: for adding a new node at any place of the Linked List"<<endl;
cout<<" e: for deleting a node from the beginning of the Linked List"<<endl;
cout<<" f: for deleting a node from the end of the Linked List"<<endl;
cout<<" g: for deleting a node from any place of the Linked List"<<endl;
cout<<" h: for destroying the Linked List "<<endl;
cin>>ch;
switch(ch)
{
case 'a': {clrscr( );
x.initila_D();
x.write_D();
break;}

case 'b': {clrscr( );


cout<<" Enter the data for the new node ( First node) :";
cin>>m;
x.adfirst_D(m);
x.write_D();
break;}

case 'c': {clrscr( );


cout<<" Enter the data for the new node ( Last node) :";
cin>>m;
x.addend_D(m);
x.write_D();
break;}

case 'd': {clrscr( );


cout<<" Enter the data for the new node ( Any place ) \n"
<<" You have to select the new node within the data: " ;
cin>>m;
x.adany_D(m);
x.write_D();
break;}

case 'e': { clrscr( );


x.defirst_D();
x.write_D();
break;}

case 'f': {clrscr( );


x.delast_D();
x.write_D();
break;}

case 'g': {clrscr( );


cout<<" Enter the data for the node (Any place) \n"
<<" You have to select the node within the Linked List: " ;
cin>>m;
x.deany_D(m);
x.write_D();
break; }

case 'h': {clrscr( );


x.destroy_D();
x.write_D();
break;}

default: {clrscr( ) ;
exit(5);
}
}
}
‫وكما ذكرنا سابقا فعند تنفيذ ألبرنامج‪ ،‬سوف تُنشأ قائمة متصلة مزدوجة ويُطلب ِمنا إدخال‬
‫ألبيانات لكل عقدة ُمبتدا ِمن ألرأس ثم ألمرور بألعُقد ألباقية حتى أألخيرة‪.‬‬
‫بعدھا سوف تظھر لنا ألشاشة ألتالية‪:‬‬

‫‪SELECT A CHARACTER TO RUN ONE OF THE FOLLOWING:‬‬


‫__________________________________________‬

‫‪a: for the initialization of the Linked List‬‬


‫‪b: for adding a new node at the beginning of the Linked List‬‬
‫‪c: for adding a new node at the end of the Linked List‬‬
‫‪d: for adding a new node at any place of the Linked List‬‬
‫‪e: for deleting a node from the beginning of the Linked List‬‬
‫‪f: for deleting a node from the end of the Linked List‬‬
‫‪g: for deleting a node from any place of the Linked List‬‬
‫‪h: for destroying the Linked List‬‬

‫حيث يتوجب علينا إختيار واحد من ألحروف ) من ‪ a‬إلى ‪ ( h‬وبخالف ذلك سوف نخرج من‬
‫ألبرنامج‪.‬‬

‫‪Circular Double Linked List‬‬ ‫‪ .١٧‬ألقا ئمة ألمتصلة ألمزدوجة ألدورانية‬

‫في ألمناقشات ألسابقة الحظنا بأن ألقائمة ألمتصلة ألمزدوجة يؤشر فيھا مؤشر ألعقدة أالخيرة‬
‫‪ last‬على ألفراغ ‪ .NULL‬فإذا أشر مؤشر ألعقدة أالخيرة على ألعقدة ألرأس‪:‬‬

‫; ‪last -> after = head‬‬

‫وأشرمؤشر ألعقدة ألرأس على ألعقدة أالخيرة‪:‬‬

‫; ‪head -> before = last‬‬

‫فإن ألقائمة ألمتصلة ألمزدوجة سوف تسمى ألقائمة ألمتصلة ألمزدوجة ألدورانية )‪.(Circular‬‬
‫ألشكل ‪ ٦٢ -١‬يوضح ذلك‪:‬‬

‫‪head‬‬ ‫‪last‬‬

‫ألشكل ‪ ٦٢-١‬ألقائمة ألمتصلة ألمزدوجة ألدورانية‬

‫وعليه‪ ،‬النشاء قائمة متصلة مزدوجة دورانية ناتبع ألخطوات ألبرمجية أالتية‪:‬‬
// Program Chr1_04.cpp
# include<iostream.h>

struct nod {
int Data ;

nod *after ;
nod *before ;
};
nod *head, *cura, *curb,*last ;
const int size = ٣ ;
void create_CD ( )
{
head = new nod ;
head -> before = NULL ;
head -> after = NULL ;
cura = head ;
curb = head ;
for (int i = 1 ; i <= size ; i++ )
{
cura -> after = new nod ;
cura = cura -> after ;
cura -> before = curb;
curb = curb -> after ;
}
last = cura ;
last -> after = head ;
head -> before = last ;
}

main( )
{ create_CD ( ) ; }
Inserting data ‫ إدخال ألبيانات‬.١٨

‫ھنا نوضح كيفية إدخال ألبيانات لكل عقدة من ألعقد ألمتكونة منھا ألقائمة ألمتصلة ألمزدوجة‬
:‫ألدورانية إن ألدالة ستكون على ألنحو أالتي‬
void read_CD ( )
{ cout<< "Enter the value for the head : " ;
cin>> head -> Data ;
cura = head ;
while( cura -> after)
{
‫; " ‪cout<< " Enter the values of the items :‬‬
‫; ‪cura = cura -> after‬‬
‫; ‪cin>> cura -> Data‬‬
‫}‬
‫}‬

‫نالحظ بأن عملية أالدخال لن تختلف على أالطالق مع تلك ألعملية في حالة ألقائمة ألمتصلة‬
‫ألمزدوجة‬
‫حيث يطلب ِمنا ألبرنامج إدخال قيم لكل من‪:‬‬

‫ ألرإس‬
‫ ثالثة عقد متبقية تشمل كذلك ألعقدة أالخيرة‬

‫مثال ذلك عند إدخال ألقيم‪:‬‬

‫ ‪١‬‬
‫ ‪7 ،٥ ،٢‬‬

‫فإن ألقائمة ألمتصلة ستأخذ ألشكل ‪ ٦٣ -١‬وكما يلي‪:‬‬

‫‪head‬‬ ‫‪last‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪7‬‬

‫‪*head‬‬ ‫‪*last‬‬
‫ألشكل ‪ ٦٣ -١‬قائمة متصلة مزدوجة دورانية‬

‫‪ .١٩‬ألعمليات أالساسية على ألقائمة ألمتصلة ألمزدوجة ألدورانية‬


‫‪Basic Operations on a Circular Double Linked List‬‬

‫يتضمن ھذا ألجزء من ألفصل ألمواضيع أالتية‪:‬‬

‫ حشر ‪ insert‬عقدة في موقع معين من ألقائمة ألمتصلة‬


‫ حذف ‪ delete‬عقدة من موقع معين في ألقائمة ألمتصلة‬

‫حشر عقدة‪:‬‬
‫لحشر عقدة جديدة في بداية ألقائمة ألمتصلة ألمزدوجة ألدورانية نستخدم ألدالة أالتية‪:‬‬

‫)‪void adfirst_D(int m‬‬


‫{‬
‫)‪if(!head‬‬
‫{‬
‫;‪head = new nod‬‬
‫;‪head->Data = m‬‬
‫;‪head -> after = NULL‬‬
‫;‪last = head‬‬
‫;‪last -> before = NULL‬‬
‫}‬
‫‪else‬‬
‫{‬
‫;‪nod *temp = new nod‬‬
‫;‪temp -> Data = m‬‬
‫;‪temp -> after =head‬‬
‫; ‪head -> before = temp‬‬
‫; ‪last -> after = temp‬‬
‫;‪temp -> before = last‬‬
‫;‪head = temp‬‬
‫}‬
‫}‬

‫يفترض ألجزء أالول من ألدالة عدم إحتواء ألقائمة ألمتصلة ألمزدوجة ألدورانية على أية عقدة‬
‫وعليه فإن ألعقدة ألجديدة ستكون ھي ألعقدة ألرأس وھي ألعقدة أالخيرة في نفس ألوقت‪ .‬في حين‬
‫إن لم تكن ألقائمة ألمتصلة ألمزدوجة ألدورانية خالية فإننا نستطيع إضافة ألعقدة ألجديدة في‬
‫ألموقع ألمناسب‪.‬‬
‫ألشكل ‪ ٦٤ -١‬يوضح ألعبارتين من أالمر ‪ else‬وھي‪:‬‬

‫;‪nod *temp = new nod‬‬


‫;‪temp -> Data = m‬‬

‫‪head‬‬ ‫‪last‬‬

‫‪1‬‬ ‫‪2‬‬ ‫‪5‬‬ ‫‪7‬‬

‫‪temp‬‬

‫‪m‬‬

‫‪*temp‬‬
‫ألشكل ‪ 64 -١‬إضافة عقدة جديدة لقائمة متصلة مزدوجة‬
‫أما ألعبارات‪:‬‬

‫;‪temp -> after =head‬‬


‫; ‪head -> before = temp‬‬
‫; ‪last -> after = temp‬‬
‫;‪temp -> before = last‬‬
‫;‪head = temp‬‬

‫فھي تعمل على ربط ألعقدة ألجديدة بألعقدة ألرأس ثم يتم إطالق إسم ألرأس على ألعقدة ألجديدة‪.‬‬

‫أما عند إضافة عقدة جديدة في نھاية ألقائمة ألمتصلة ألمزدوجة فيمكن تطبيق ألدالة أالتية‪:‬‬

‫)‪void addend_CD(int n‬‬


‫{‬
‫) ‪if( !last‬‬
‫{‬
‫;‪last = new nod‬‬
‫;‪last->Data = n‬‬
‫; ‪last -> after = NULL‬‬
‫; ‪last -> before = NULL‬‬
‫; ‪head = last‬‬
‫}‬
‫‪else‬‬
‫{‬
‫; ‪nod *temp = new nod‬‬
‫; ‪temp -> Data = n‬‬
‫; ‪last -> after = temp‬‬
‫; ‪temp -> before = last‬‬
‫; ‪last = temp‬‬
‫; ‪last -> after = head‬‬
‫; ‪head -> before = last‬‬
‫}‬
‫}‬

‫وكما ذكرنا سابقا وبإفتراض بأن ألجزء أالول من ألدالة يتعامل مع قائمة متصلة مزدوجة‬
‫دورانية ال تحتوي على أية عقدة وعليه فإن ألعقدة ألجديدة ستكون ھي ألعقدةأالخيرة وھي ألعقدة‬
‫ألرأس في نفس ألوقت‪ .‬في حين إن لم تكن ألقائمة ألمتصلة ألمزدوجة ألدورانية خالية فإننا‬
‫نستطيع إضافة ألعقدة ألجديدة‪.‬‬

‫أما عند إضافة عقدة جديدة في مكان ما من ألقائمة ألمتصلة ألمزدوجة ألدورانية فألمسألة لن‬
‫تختلف وعلى أالطالق عن إضافة عقدة جديدة في مكان ما من ألقائمة ألمتصلة ألمزدوجة ھذا ما‬
‫نالحظه في ألدالة أالتية ‪:‬‬

‫)‪void adany_CD (int me‬‬


‫{‬
‫; ‪nod *temp, *ptr1‬‬
‫; ‪temp = new nod‬‬
‫; ‪temp -> Data = me‬‬
‫; ‪cura = head‬‬
‫) ‪while (cura -> Data < me‬‬
‫{‬
‫; ‪ptr1 = cura‬‬
‫; ‪cura = cura -> after‬‬
‫}‬
‫;‪ptr1 -> after=temp‬‬
‫; ‪temp-> after = cura‬‬
‫}‬

‫حذف عقدة‪:‬‬

‫إن عملية حذف عقدة من قائمة متصلة مزدوجة دورانية تشبه عملية حذف عقدة من قائمة متصلة‬
‫مزدوجة‪ .‬إن ألحذف سيكون من ألمواقع أالتية‪:‬‬

‫ بداية ألقائمة ألمتصلة ألمزدوجة‬


‫ أية موقع من ألقائمة ألمتصلة ألمزدوجة‬
‫ نھاية ألقائمة ألمتصلة ألمزدوجة‬

‫إن أالختالف ھو في ألتعامل مع ألمؤشرات ألسابق وألالحق‪.‬‬


‫فلحذف عقدة من بداية ألقائمة ألمتصلة ألمزدوجة ألدورانية نستخدم ألدالة أالتية‪:‬‬

‫) (‪void defirst_CD‬‬
‫{‬
‫;‪cura = head‬‬
‫;‪head = head -> after‬‬
‫;‪delete cura‬‬
‫; ‪head -> before = last‬‬
‫; ‪last -> after = head‬‬
‫}‬

‫ولحذف عقدة من نھاية ألقائمة ألمتصلة ألمزدوجة ألدورانية نستخدم ألدالة أالتية‪:‬‬

‫) (‪void delast_CD‬‬
‫{‬
‫; ‪curb = last‬‬
‫; ‪last = last -> before‬‬
‫;‪delete curb‬‬
‫; ‪last -> after = head‬‬
‫; ‪head -> before = last‬‬
‫}‬
‫لحذف عقدة من أية موقع في ألقائمة ألمتصلة ألمزدوجة ألدورانية ) بإستثناء ألعقدة أالولى‬
‫‪ head‬وألعقدة أالخيرة ‪ ( last‬فالمسألة لن تختلف عن ألدالة وألتي تم إستخدامھا في ألقائمة‬
‫ألمتصلة ألمزدوجة‪:‬‬

‫) ‪void deany_CD (int me‬‬


‫{‬
‫;)‪assert(head -> Data != me‬‬
‫;)‪assert(last -> Data != me‬‬

‫;‪nod *ptr1‬‬
‫; ‪cura = head‬‬
‫)‪while (cura -> Data != me‬‬
‫{‬
‫; ‪ptr1 = cura‬‬
‫; ‪cura = cura -> after‬‬
‫}‬
‫; ‪curb = cura -> after‬‬
‫; ‪ptr1 -> after = curb‬‬
‫; ‪curb -> before = ptr1‬‬
‫; ‪delete cura‬‬
‫}‬

‫‪Exercises‬‬ ‫‪ .٢٠‬تمارين‬

‫س ‪ 1‬أجب عن أالسئلة أالتية بكلمة صح أو خطأ‪:‬‬

‫ألقائمة ألمتصلة تتكون من مجموعة من ألدوال‪.‬‬ ‫•‬


‫عنوان ألعقدة أالولى في ألقائمة ألمتصلة يخزن في موقع مستقل يسمى ألرأس )‪.(head‬‬ ‫•‬
‫للبحث عن عنصر معين في قائمة متصلة يتطلب ألتجول داخل ألقائمة‪.‬‬ ‫•‬
‫يستخدم ألمؤشر ألتيار )‪ (cur‬وألخارج عن ألعقد ألمتصلة في إجراء عملية ألتجول‪.‬‬ ‫•‬
‫كل عقدة من عقد ألقائمة ألمتصلة تحمل نوع بيانات مختلف عن أالخرى‪.‬‬ ‫•‬
‫اليمكن حذف ألعقدة أالولى من ألقائمة ألمتصلة إال بعد تخصيص عقدة بديلة لھا‪.‬‬ ‫•‬
‫يمكن إجراء تبديل ألبيانات بين عقدة وأخرى من نفس ألقائمة ألمتصلة‪.‬‬ ‫•‬
‫إذا أشرت ألعقدة أالخيرة على ألعقدة أالولى فإن ألقائمة ألمتصلة ألمفردة سوف تسمى‬ ‫•‬
‫قأئمة متصلة مفردة دورانية‪.‬‬
‫تحتوي كل عقدة في ألقائمة ألمتصلة ألمزدوجة على مؤشرين إثنين‪.‬‬ ‫•‬
‫يمكن ترتيب ألعقد في ألقائمة ألمتصلة ترتيبا تنازليا أو تصاعديا‪.‬‬ ‫•‬
‫ال يمكن ألتجول في ألقائمة ألمتصلة ألمزدوجة من كال أالتجاھين‪.‬‬ ‫•‬
‫تستخدم ألكلمة ألمحجوزة ‪ new‬عند إضافة عقدة جديدة‪.‬‬ ‫•‬
‫س ‪ 2‬إختر أالجابة ألصحيحة في كل مما يلي‪:‬‬
‫• تعرف ألقئمة ألمتصلة بأنھا مجموعة من‬

‫ب( ألعقد‬ ‫أ( ألمتغيرات‬


‫د( ألمواقع‬ ‫ج( ألقيم‬

‫• في ألقائمة ألمتصلة ألمزدوجة ألدورانية ‪ ،‬مؤشر ألعقدة أالخيرة يؤشر على ألعقدة‪:‬‬

‫ب( ألرأس‬ ‫أ( أالخيرة‬


‫د( ألعشوائية‬ ‫ج( ألفراغ‬

‫• ألعبارة‪ head -> cura -> data ; :‬تعني طباعة ألبيانات في ألعقدة ‪:‬‬

‫ب( أالخيرة‬ ‫أ( ألرأس‬


‫د( ألسابقة لالخيرة‬ ‫ج( ألتالية للرأس‬

‫• ألعبارة‪ last -> curb -> data ; :‬تعني طباعة ألبيانات في ألعقدة ‪:‬‬

‫ب( أالخيرة‬ ‫أ( ألرأس‬


‫د( ألسابقة لالخيرة‬ ‫ج( ألتالية للرأس‬

‫• أألدالة ألتي تعمل على ھدم أألقئمة ألمتصلة ألمزدوجة أألدورانية تسمى‪:‬‬

‫ب( ) (‪write_CD‬‬ ‫أ( ) (‪initila_CD‬‬


‫د( ) (‪addany_CD‬‬ ‫ج( ) (‪destroy_CD‬‬

‫س ‪ 3‬ما ھي مخرجات ألدالة أالتية‪:‬‬

‫; ‪node *ptr‬‬
‫) (‪void pll‬‬
‫{‬
‫; ‪ptr = head‬‬
‫)‪while(ptr‬‬
‫{‬
‫; ‪cout<<ptr -> data‬‬
‫; ‪ptr = ptr -> link‬‬
‫}‬
‫; ‪cout<< endl‬‬
‫}‬
‫س ‪ 4‬أكتب ألدالة ألتي تعمل على حساب عدد ألعقد في قائمة متصلة مزدوجة دورانية‪.‬‬

‫س ‪ 5‬أكتب ألدالة ألالزمة لحساب موقع ألعقدة ألتي تحمل أكبر قيمة في قائمة متصلة مفردة‪.‬‬

‫س ‪ 6‬أكتب ألدالة ألالزمة لحساب موقع ألعقدة ألتي تحمل أصغر قيمة في قائمة متصلة مزدوجة‪.‬‬

‫س ‪ 7‬أكتب ألدالة ألالزمة لتبديل قيم عقدتين متجاورتين في قائمة متصلة مفردة‪.‬‬

‫س ‪ 8‬أكتب ألدالة ألالزمة لحساب عدد ألعقد ألمحصورة بين ألعقدة ألرأس وألعقدة أالخيرة في‬
‫قائمة متصلة مفردة دورانية‪.‬‬

‫س ‪ 9‬أكتب ألدالة ألالزمة لعكس قيم ألبيانات في عقد لقائمة متصلة مفردة‪.‬‬

‫س ‪ 10‬إذا كانت ألعقدة ‪ x‬ھي إحدى عقد قائمة متصلة مزدوجة‪ ،‬أكتب ألدالة ألالزمة لتبديل‬
‫ھذه ألعقدة مع ألعقدة ألرأس‪.‬‬

‫س ‪ 11‬إذا كانت ألعقدة ‪ y‬ھي إحدى عقد قائمة متصلة مزدوجة دورانية‪ ،‬أكتب ألدالة ألالزمة‬
‫لتبديل ھذه ألعقدة مع ألعقدة أالخيرة‪.‬‬

‫س ‪ 12‬إذا كانت ‪ A‬تمثل قائمة متصلة مزدوجة بياناتھا قيم صحيحة ) سالبة وموجبة ( أكتب دالة‬
‫تنشئ قائمتين متصلتين أالولى ‪ B‬مفردة وألثانية ‪ C‬مفردة دورانية بحيث تضع في ألقائمة‬
‫أالولى ألقيم ألسالبة وفي ألثانية ألقيم ألسالبة‪.‬‬

‫‪ A‬و ‪ B‬قائمتين متصلتين مزدوجتين فإحسب ما يلي‪:‬‬ ‫س ‪ 13‬إذا كانت‬


‫‪ C = A + 2B‬حيث أن ‪ C‬قائمة متصلة مزدوجة‬ ‫‪-‬‬
‫‪ C = 3A – B‬حيث أن ‪ C‬قائمة متصلة مفردة‬ ‫‪-‬‬
‫‪ C = 3A * 2B‬حيث أن ‪ C‬قائمة متصلة مفردة دورانية‬ ‫‪-‬‬

‫س ‪ 14‬إذا كانت ‪: A‬‬

‫‪Q1. Given a single linked list with ten nodes, write the required function for each of‬‬
‫‪the‬‬
‫‪following:‬‬
‫‪• Swap between node number 2 and node number 9‬‬
‫‪• Put the first node after the last node‬‬
‫‪• Delete the mid node‬‬
‫‪• Return the data at node number 6‬‬
‫‪• Destroy the last four nodes‬‬
‫‪• Return the number of the nodes‬‬

You might also like