‫برمجة تراكيب البيانات‬

‫‫المحاضرة السابعة‬
‫القوائم المتصلة‬

‫‪Linked List‬‬

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

‫هنا يأتي دور القائمة المتصلة لكي تحل لنا هذه المشكلة !!‬
‫تعريف القائمة المتصلة ‪-:‬‬
‫هي عبارة عن هيكل(تركيب) بيانات مكون من عقد ‪ nodes‬مرتبطة مع بعضها البعض ‪ ،‬وهلا بداية وهناية‪.‬‬
‫انظر الصور التوضيحية التالية‪:‬‬
‫عقدة‬

‫عقدة‬
‫تتكون القائمة المتصلة من عدة عقد‬

‫‪NULL‬‬

‫عقدة‬
‫‪NULL‬‬

‫‪HEAD‬‬

‫عقدة‬

‫تتميز القائمة المتصلة بالقدرة على حذف العناصر أثناء تشغيل البرنامج ‪HEAD‬‬

‫ما هي العقدة ؟؟‬
‫العقدة هي "عنصر يف القائمة املتصلة" ‪ ،‬وجمموعة العقد تكون لنا "قائمة متصلة" ‪.‬‬
‫بنفس فكرة املصفوفة ‪ ،،‬فكل عنصر فيها يسمى" عنصر يف املصفوفة "‪ ،‬وجمموعة العناصر تكون لنا "مصفوفة" ‪.‬‬
‫كل عقده حتتوي على اآليت ‪:‬‬

‫إعداد األستاذ‪/‬حذيفة عبد الرحمن‬

‫‪1‬‬

‫برمجة‫تراكيب‫البيانات‬

‫‪ .1‬بيانات‬

‫‪data‬‬

‫‪ .2‬مؤشر إلى عقدة أخرى‬

‫‪pointer to another node‬‬

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

‫هنا يتم ختزين البيانات واليت‬
‫ميكن أن تكون عدد أو حرف‬

‫أمامها وهكذا تنتج لدينا قائمة‬
‫متصلة‬

‫أو أي شيء أخر‬
‫عقدة‬
‫‪Node‬‬

‫وترتبط العقد مع بعضها حتى تكون لنا قائمة متصلة ‪.‬‬
‫بداية ونهاية القائمة المتصلة‬
‫املؤشر ‪ head‬هو مؤشر ألول عقدة يف القائمة املتصلة ‪ ،،‬وإذا كانت القائمة خالية فانه سيشري إىل ‪ NULL‬واليت تعين‬
‫فارغ أو ‪0‬‬
‫صور توضيحية‬
‫‪HEAD‬‬

‫‪NULL‬‬

‫قائمة متصلة فارغة من العقد‬

‫‪NULL‬‬

‫‪3‬‬

‫قائمة متصلة تحوي عقدة واحدة‬

‫إعداد األستاذ‪/‬حذيفة عبد الرحمن‬

‫‪2‬‬

‫‪HEAD‬‬

‫برمجة‫تراكيب‫البيانات‬

‫عقدة‬

‫‪D‬‬

‫‪C‬‬

‫‪A‬‬

‫قائمة متصلة تحوي عدة عقد‬

‫‪NULL‬‬

‫‪‬‬

‫‪B‬‬

‫عقدة‬
‫‪HEAD‬‬

‫املؤشر ‪ head‬هو مؤشر ألول عقدة ‪ ،،‬وأول عقدة تشري إىل الثانية ‪،،‬والعقدة الثانية تشري إىل‬
‫العقدة الثالثة ‪،‬و‪ ...‬وهكذا حىت نصل إىل عقدة تشري إىل ‪ NULL‬واليت تكون هي العقدة األخرية‬
‫يف القائمة ‪.‬‬

‫مشكلة المؤشر ‪!! head‬‬
‫ألنه لو حذف أو تبدلت قيمته ال نستطيع التعامل مع القائمة وستظهر لنا مشكلة تسرب الذاكرة !!‬
‫والصور التالية توضح قوائم مختلفة‬
‫هذه الصورة لقائمة بدون مشاكل ‪:‬‬
‫عقدة‬
‫‪NULL‬‬

‫عقدة‬

‫تتكون القائمة المتصلة من عدة عقد‬

‫‪HEAD‬‬

‫أما هذه‪:‬‬
‫عقدة‬
‫‪NULL‬‬

‫الحظ أن المؤشر‬

‫‪HEAD‬‬

‫عقدة‬
‫أصبح يشير إلى شيء أخر‬

‫هنا تأتي المشكلة !!‬
‫املؤشر ‪ head‬وهو الذي كان يشري إيل أول عقدة ‪ ،،‬أصبح يشري إىل شيء آخر !!‬
‫حاليا يف هذا الوضع ال نستطيع الوصول للقائمة وال نستطيع حذفها ‪.‬‬
‫إعداد األستاذ‪/‬حذيفة عبد الرحمن‬

‫‪3‬‬

‫‪HEAD‬‬

‫برمجة‫تراكيب‫البيانات‬

‫إذن ما هو الحل‬

‫احلل يكمن يف انه جيب تذكر القيمة اليت ستكون للمؤشر ‪ head‬يف كل سطر تقوم بكتابته‬
‫‪‬‬

‫ميكن إنشاء عدد كبري جداً حيث يعتمد باملقام األول على حجم الذاكرة‪.‬‬

‫‪‬‬

‫القائمة املتصلة تشبه املصفوفة باستثناء الروابط بني العقد‬
‫والذي جيعل مرنه القائمة املتصلة هي الروابط ‪ ،‬حيث تستطيع حذف العقدة "بتغيري الروابط"‬
‫وكذلك إنشاء عقدة جديدة "أيضاً بتغيري الروابط "‪.‬‬

‫استخدامات القوائم المرتبطة ‪:‬‬
‫القوائم املتصلة على سبيل املثال تستخدم بشكل أساسي داخل البنوك ‪ ،‬فحساب كل شخص هو عبارة عن عقدة‬
‫‪ node‬فهي تستخدم حلفظ البيانات بشكل مؤقت وتتعامل مع البيانات ‪ ،‬وتستطيع التطبيقات أن تشكل القائمة من‬
‫خالل قاعدة بيانات أو أن حتفظ القائمة داخل قاعدة بيانات ‪ ،‬وتستطيع أن جتري على العقد العمليات اليت ترغبها ‪،‬‬
‫تستطيع أن تضيف حساب شخص بأي مكان من القائمة ‪ ،‬تستطيع حذف حساب شخص مىت ما أردت ومن أي‬
‫مكان بالقائمة ‪ ،‬تستطيع ترتيب احلسابات ‪ ،‬عرضها ‪ ،‬حتريرها وكذلك تستطيع متديد القائمة وإضافة عناصر جديدة من‬
‫العمليات املختلفة بكل سهوله وكفاءة‪ ،‬على عكس املصفوفات اليت تتطلب حتريك العناصر ‪.‬‬
‫أنواع القوائم المتصلة ‪:‬‬
‫يوجد عدة أنواع أمههما ‪:‬‬

‫‪ -1‬القائمة المتصلة المفردة‬

‫‪single Linked List‬‬

‫‪ -2‬القائمة المتصلة المزدوجة‬
‫‪ -3‬القائمة المتصلة الدائرية‬

‫إعداد األستاذ‪/‬حذيفة عبد الرحمن‬

‫‪double Linked List‬‬

‫‪circular List Linked‬‬

‫‪4‬‬

‫برمجة‫تراكيب‫البيانات‬

‫أوال ‪ :‬القائمة المتصلة المفردة ‪: single Linked List‬‬

‫وفيها كل عقدة تشري إىل اليت أمامها ‪ ،،‬أي يف كل عقدة يوجد مؤشر واحد فقط‪.‬‬
‫عقدة‬
‫قائمة متصلة‬

‫‪NULL‬‬

‫عقدة‬
‫مفردة ‪single Linked List‬‬

‫‪HEAD‬‬

‫وهذا شكل العقدة‬
‫هنا يتم ختزين البيانات واليت‬
‫ميكن أن تكون عدد أو حرف أو أي‬
‫شيء أخر‬

‫أما هنا فيوجد عنوان العقدة اليت تليها‬
‫‪ ،‬فكل عقدة تشري إىل اليت أمامها‬
‫وهكذا تنتج لدينا قائمة متصلة‬

‫شكل العقدة في قائمة متصلة مفردة‬
‫كما ذكرنا بان القائمة املتصلة هي عبارة عن سلسلة من العقد )‪، ( nodes‬إذن سنقوم اآلن ببناء تركيبة لتمثل هذه‬
‫العقد ‪ ،‬وذكرنا بان كل عقدة حتتوي على قسمني‬
‫القسم األول ‪ :‬قسم البيانات‬
‫القسم الثاني ‪ :‬مؤشر لعقدة أخرى أو لـ‬

‫‪null‬‬

‫اآلن سنأخذ مثال على تركيبة بيانات متثل لنا العقدة اليت نرغب بتصميمها ‪ ،‬وهي عبارة عن عقدة حتتوي على‬
‫قسم البيانات ‪ :‬رقم صحيح ‪ ،‬قسم املؤشر‪.‬‬
‫‪struct node‬‬
‫{‬
‫;‪int number‬‬
‫;‪node *next‬‬
‫;}‬
‫;‪typedef node *node_ptr‬‬
‫بنية ‪struct‬‬

‫فيما سبق قمنا بتعريف‬
‫صحيحة‪ ،‬واملتغري الثاين هو ‪next‬‬
‫األخرى‪.‬‬
‫إعداد األستاذ‪/‬حذيفة عبد الرحمن‬

‫امسها ‪ node‬حتتوي على متغريين ‪ ،‬األول هو متغري ‪ number‬لتخزين أرقام‬
‫وهو مؤشر من نوع الرتكيبة نفسها ‪ node‬وسنستخدمه للتأشري على العقد‬
‫‪5‬‬

‫برمجة‫تراكيب‫البيانات‬

‫بعد الرتكيبة قمنا باستخدام األمر ‪ typedef‬بتعريف نوع بيانات من نوع أخر وهو ‪ * node_ptr‬من نوع الرتكيبة‬
‫‪node‬‬

‫األمر‬

‫‪typedef‬‬

‫للصيغة‪:‬‬

‫يقوم بتعريف نوع من نوع أخر وفقا‬
‫;النوع املغري له النوع األصلي‬

‫‪typedef‬‬

‫العمليات على القوائم المتصلة ‪-:‬‬
‫مثل‪:‬‬

‫هناك العديد من العمليات اليت ميكن أن تتم على القائمة‬
‫( اإلضافة ‪ -‬التعديل ‪ -‬احلذف ‪ -‬عرض العناصر –البحث)‪.‬‬
‫نبدأ‬

‫أوالا باإلضافة‪.‬‬
‫طرق‪:‬‬

‫وهلا أربعة‬
‫‪ -1‬إضافة أول عقدة ‪.‬‬
‫‪-2‬اإلضافة من اليمني (النهاية )‪.‬‬
‫‪-3‬اإلضافة من اليسار ( البداية )‪.‬‬
‫‪ -4‬اإلضافة من الوسط‪.‬‬
‫أوالا ‪ :‬إضافة أول‬

‫عقدة‪:‬‬

‫اآلن ‪ ،‬ال يوجد لدينا قائمة ‪ ،‬وننوي إنشاء قائمة عن طريق إنشاء أول عقدة هبذه القائمة ‪ ،‬ونتذكر بأننا أنشئنا‬
‫تركيبة لكل عقدة ( يف مثالنا السابق كل عقدة حتتوي على ‪ :‬البيانات ( رقم صحيح) واملؤشر‪.‬‬
‫)‪node_ptr make_new_node(int x‬‬
‫{‬
‫;‪node_ptr p‬‬
‫;‪p=new node‬‬
‫;‪p->number =x‬‬
‫;‪p->next =NULL‬‬
‫;‪return p‬‬
‫}‬

‫اآلن لدينا داخل العنوان‬

‫‪ p‬عنصرين‪:‬‬
‫بـالوسيط‪x‬‬

‫‪ number‬ونساويها‬
‫‪ next‬وهو املؤشر الذي يؤشر للعقدة التالية ونساويه بـ‪NULL‬‬
‫إعداد األستاذ‪/‬حذيفة عبد الرحمن‬

‫‪6‬‬

‫برمجة‫تراكيب‫البيانات‬

‫ثانيا ‪:‬اإلضافة من اليمين (النهاية )‪.‬‬

‫انتهينا من النقطة رقم ‪ 1‬ولدينا اآلن عقدة ومؤشرها يؤشر إىل ‪ NULL‬كما هو‬

‫بالصورة‪:‬‬

‫‪node‬‬
‫‪Null‬‬

‫خطوات إضافة عقدة من‬

‫النهاية‪:‬‬

‫ننشئ عقدة جديدة وجنعلها تؤشر‬

‫إىل‪NULL‬‬

‫‪node‬‬
‫‪Null‬‬

‫جنعل العقدة األوىل بدال من أن تأشر إىل ‪ NULL‬تأشر إىل العقدة‬

‫اجلديدة‪:‬‬

‫‪node‬‬

‫‪node‬‬
‫‪Null‬‬

‫)‪void insert_last(node_ptr &first‬‬
‫{‬
‫;‪int x‬‬
‫;"‪cout<<"Enter value in new node \n‬‬
‫;‪cin>>x‬‬
‫;‪node_ptr p,q‬‬
‫)‪if(first==NULL‬‬
‫{‬
‫;)‪first=make_new_node (x‬‬
‫}‬
‫‪else‬‬
‫{‬
‫;‪p=first‬‬
‫)‪while(p->next!=NULL‬‬
‫{‬
‫; ‪p=p->next‬‬
‫}‬
‫إعداد األستاذ‪/‬حذيفة عبد الرحمن‬

‫‪7‬‬

‫برمجة‫تراكيب‫البيانات‬

‫;)‪q=make_new_node (x‬‬
‫;‪p->next =q‬‬
‫}‬
‫}‬

‫الشرح‬

‫‪:‬‬

‫‪ .1‬أنشأنا متغريين ‪ q ,p‬من النوع‬
‫القائمة‪.‬‬
‫‪ .2‬جعلنا ‪ p‬يساوي عنوان ‪ first‬أي عنوان القائمة‪.‬‬
‫‪ .3‬حلقة تكرار للتنقل عرب العقد القائمة‪ ،‬تستمر حلقة التكرار طاملا أن العقدة ال تؤشر إىل‪NULL :‬‬
‫‪node_ptr‬‬

‫ليمثل املتغري ‪ q‬العقدة اجلديدة ‪ ،‬أما املتغري ‪ p‬للتنقل عرب عقد‬

‫شرح مفصل للدالة‬

‫للوصول إىل هناية احللقة نكتب شرط التكرار هو‬

‫مثال‪:‬‬

‫أن يستمر التقدم حىت نصل إىل العقدة اليت تؤشر إىل ‪NULL‬‬
‫;‪p=first‬‬
‫)‪while(p->next!=NULL‬‬
‫{‬
‫;‪p=p->next‬‬
‫}‬

‫لنفرتض وجود قائمة حتتوي على ‪ 3‬عقد ونريد الوصول إىل آخر عقدة ‪ ،‬إذن عندها سنتنقل على القائمة حىت‬
‫نصل إىل العقدة اليت تؤشر إىل ‪ NULL‬اآلن لنفرتض فعال وجود هذه القائمة كما هو موضح يف الصورة‬
‫‪node‬‬

‫‪node‬‬

‫‪node‬‬

‫‪Null‬‬
‫‪3‬‬

‫أوال ‪ :‬سنضع‬

‫‪1‬‬

‫‪2‬‬

‫‪p=first‬‬

‫حيث ‪ first‬هو عنوان القائمة أي عنوان أول عقدة يف القائمة ‪ ،‬واآلن أصبح املتغري ‪ p‬حيمل هذا‬

‫ثاني ا ‪:‬‬

‫)‪while(p->next!=NULL‬‬
‫{‬
‫;‪p=p->next‬‬
‫}‬

‫كرر طاملا أن ‪ next‬ال يساوي‬
‫إعداد األستاذ‪/‬حذيفة عبد الرحمن‬

‫‪NULL‬‬

‫سنطبق هذا املثال على القائمة اليت‬

‫‪8‬‬

‫افرتضناها‪:‬‬

‫العنوان‪.‬‬

‫برمجة‫تراكيب‫البيانات‬
‫‪node‬‬

‫‪node‬‬

‫‪node‬‬

‫‪Null‬‬
‫‪3‬‬

‫‪2‬‬

‫‪p->next=2‬‬

‫اآلن عندما‬

‫‪1‬‬

‫‪p=1‬‬

‫نقول‪:‬‬
‫‪p=p->next‬‬

‫هذا يعين أن‬

‫‪p‬‬

‫قد تقدم خطوة إىل األمام وأصبح اآلن بالعقدة‬
‫‪node‬‬

‫التالية‪.‬‬

‫‪node‬‬

‫‪node‬‬

‫‪Null‬‬
‫‪3‬‬

‫‪2‬‬

‫‪p->next=3‬‬

‫‪1‬‬

‫‪p=2‬‬

‫هل ‪ p->next‬ال تساوي ‪ NULL‬؟‬
‫نعم ال تساوي ‪ NULL‬ألهنا تساوي عنوان العقدة ‪ 3‬إي أهنا تؤشر للعقدة ‪3‬‬
‫‪p=p->next‬‬
‫‪node‬‬

‫‪node‬‬

‫‪node‬‬

‫‪Null‬‬
‫‪2‬‬

‫‪3‬‬

‫‪p->next=Null‬‬

‫‪1‬‬

‫‪p=3‬‬

‫هل ‪ p->next‬ال تساوي ‪ NULL‬؟‬
‫ال ‪ ،‬إهنا تساوي ‪ NULL‬إذن انتهت حلقة التكرار وأصبحنا اآلن بالعقدة‬
‫أما ‪ q‬فأصبح يؤشر إىل عقدة جديدة من خالل الكود‬

‫األخرية ‪.‬‬

‫السابق‪.‬‬

‫‪p->next =q‬‬

‫اآلن أصبحت العقدة األخرية بدال من أن تؤشر إىل ‪ NULL‬تؤشر إىل عنوان العقدة‬
‫إعداد األستاذ‪/‬حذيفة عبد الرحمن‬

‫‪9‬‬

‫اجلديدة‪.‬‬

‫برمجة‫تراكيب‫البيانات‬

‫ثالثا ‪:‬اإلضافة من اليسار ( البداية )‪.‬‬

‫هنا الوضع خمتلف قليال ‪ ،‬وأسهل بكثري ‪ ,‬وتقوم الفكرة على إنشاء عقدة جديدة ‪ ،‬وجنعلها تؤشر إىل أول عقدة‬
‫من القائمة ‪ ،‬مث جنعل عنوان القائمة هو العقدة‬

‫اجلديدة‪:‬‬
‫)‪void insert_begin(node_ptr &first‬‬
‫{‬
‫;‪int x‬‬
‫;"‪cout<<"Enter value in new node\n‬‬
‫;‪cin>>x‬‬
‫;‪p‬‬

‫‪node_ptr‬‬

‫;)‪p=make_new_node(x‬‬
‫;‪p->next=first‬‬
‫;‪first=p‬‬
‫}‬

‫قمنا بالتصريح عن ‪ p‬واليت من خالهلا منثل العقدة‬

‫اجلديدة‪.‬‬

‫;‪p->next=first‬‬

‫أي عنوان أول عقدة بالقائمة أي عنوان بداية القائمة نفسها‬
‫‪q=1‬‬
‫‪node‬‬

‫‪node‬‬

‫‪node‬‬

‫‪Null‬‬
‫‪3‬‬

‫‪1‬‬

‫‪2‬‬

‫;‪first=p‬‬

‫يقوم بإنشاء عقدة جديدة وجيعلها تؤشر ألول عقدة بالقائمة أي‬
‫‪node‬‬

‫‪p‬‬

‫‪node‬‬

‫‪node‬‬

‫‪Null‬‬
‫‪3‬‬

‫‪2‬‬

‫‪p->next=Null‬‬
‫إعداد األستاذ‪/‬حذيفة عبد الرحمن‬

‫‪10‬‬

‫‪1‬‬

‫‪p=3‬‬

‫برمجة‫تراكيب‫البيانات‬

‫‪temp->next=1‬‬
‫‪node‬‬

‫‪node‬‬

‫‪node‬‬

‫‪node‬‬

‫‪Null‬‬
‫‪3‬‬

‫‪2‬‬

‫‪node‬‬

‫‪1‬‬

‫‪node‬‬

‫‪node‬‬

‫‪Null‬‬
‫‪3‬‬

‫رابعاُ ‪:‬اإلضافة من‬

‫‪1‬‬

‫‪2‬‬

‫الوسط‪:‬‬

‫تكمن الفكرة بأن نعثر عن قيمة تدل على العقدة اليت نريد أن نضيف بعدها ‪ ،‬مثل أن نبحث عن العقدة اليت هبا‬
‫الرقم ‪ 50‬ونضيف بينها وبني العقدة اليت تليها عقدة جديدة وإلمتام ذلك نقول ‪:‬‬
‫‪ -1‬لدينا قائمة من العقد ‪ ,‬نبحث عن العقدة اليت نريد أن نضيف بعدها‪.‬‬
‫‪node‬‬

‫‪node‬‬

‫‪head‬‬

‫‪Null‬‬

‫‪ -2‬ننشأ عقدة جديدة وجنعلها تؤشر إىل العقدة اليت تلي العقدة‬
‫‪node‬‬

‫املقصودة‪.‬‬

‫‪node‬‬

‫‪head‬‬

‫‪Null‬‬

‫‪node‬‬

‫‪ -3‬جنعل العقدة املقصودة تؤشر إىل العقدة‬

‫اجلديدة‪.‬‬
‫‪node‬‬

‫‪node‬‬
‫‪Null‬‬

‫‪node‬‬
‫إعداد األستاذ‪/‬حذيفة عبد الرحمن‬

‫‪11‬‬

‫‪head‬‬

‫برمجة‫تراكيب‫البيانات‬

‫أالن نكتب دالة اإلضافة من الوسط ‪:‬‬
‫)‪void insert_middle(node_ptr &first, int n‬‬
‫{‬
‫;‪int x‬‬
‫;"‪cout<<"Entr value in new node \n‬‬
‫;‪cin>>x‬‬
‫;‪node_ptr p,q‬‬
‫)‪if(first==NULL‬‬
‫{‬
‫;)‪first=make_new_node (x‬‬
‫}‬
‫‪else‬‬
‫{‬
‫;‪p=first‬‬
‫)‪while(p->number!=n &&p->next!=NULL‬‬
‫{‬
‫; ‪p=p->next‬‬
‫}‬
‫;‪node *q =new node‬‬
‫;‪q->number=n‬‬
‫;)‪q=make_new_node (x‬‬
‫;‪q->next=p->next‬‬
‫;‪p->next =q‬‬
‫}‬
‫}‬
‫القائمة‪.‬‬

‫‪ p .1‬يساوي بداية‬
‫‪ .2‬ندخل يف حلقة تكرار وشرطها طاملا أن ‪ number‬ال يساوي القيمة املراد البحث عنها ‪ n‬ومل نصل إىل‬
‫هناية القائمة‪.‬‬
‫‪ .3‬ننشئ العقدة اجلديدة ‪ q‬وجنعلها تؤشر إىل العقدة التالية من العقدة املقصودة‪.‬‬
‫‪ .4‬جنعل العقدة املقصودة تؤشر إىل العقدة اجلديدة‪.‬‬

‫إعداد األستاذ‪/‬حذيفة عبد الرحمن‬

‫‪12‬‬

‫الحذف‪.‬‬

‫ثانيا‬
‫وله ثالثة طرق‪:‬‬

‫برمجة‫تراكيب‫البيانات‬

‫‪ .1‬احلذف من اليسار (حذف من البداية) ‪.‬‬
‫‪ .2‬احلذف من اليمني )حذف من النهاية) ‪.‬‬
‫‪ .3‬احلذف من الوسط ‪.‬‬

‫أوالا ‪:‬الحذف من اليسار (حذف من البداية)‬

‫‪removeFirst‬‬

‫حلذف عقدة باستخدام هذه الطريقة نتبع اخلطوات‬
‫‪ -1‬جنعل العقدة التالية للعقدة األوىل هي بداية القائمة‪.‬‬
‫‪-2‬تكون العقدة األوىل حرة ‪ ،‬عندها نقوم حبذفها‪.‬‬

‫لنأخذ هذه‬

‫التالية ‪:‬‬

‫الدالة‪:‬‬

‫)‪void delete_first(node_ptr &first‬‬
‫{‬
‫)‪if(first==NULL‬‬
‫{‬
‫;"‪cout<<"NO,nodes found .....\n‬‬
‫}‬
‫‪else‬‬
‫{‬
‫;‪node_ptr p‬‬
‫;‪p=first‬‬
‫;‪first=first->next‬‬
‫;‪delete p‬‬
‫}‬
‫}‬

‫ثانيا‪ :‬الحذف من اليمين )حذف من النهاية)‬

‫‪delete Last‬‬

‫هبذه الطريقة ‪ ،‬نقوم بالتنقل عرب العقد إىل أن نصل إىل العقدة اليت قبل العقدة األخرية ‪ ،‬جلعلها العقدة األخرية‬
‫أوال ‪ ،‬ومن مث حذف العقدة األخرية ‪ ،‬نلخص ذلك مبا يلي ‪:‬‬
‫‪-1‬حتديد العقدة اليت تسبق العقدة األخرية‪.‬‬
‫‪-2‬جعلها تؤشر إىل ‪ NULL‬أي أن جنعلها العقدة األخرية‪.‬‬
‫‪ -3‬حذف العقدة األخرية‪.‬‬
‫إعداد األستاذ‪/‬حذيفة عبد الرحمن‬

‫‪13‬‬

‫برمجة‫تراكيب‫البيانات‬

‫)‪void delete_last(node_ptr &first‬‬
‫{‬
‫;‪node_ptr p,d‬‬
‫;‪p=first‬‬
‫)‪if(first==NULL‬‬
‫;"‪cout<<" NO;nodes found......\n‬‬
‫)‪while(p->next->next!=NULL‬‬
‫{‬
‫;‪p=p->next‬‬
‫}‬
‫;‪d=p->next‬‬
‫;‪p->next=NULL‬‬
‫;‪delete d‬‬
‫}‬

‫ثالثا‪ :‬الحذف من الوسط‬
‫يف هذه الطريقة نبحث عن العقدة املراد حذفها ‪ ،‬مثال نبحث بواسطة القيمة ‪ number‬عندها نستطيع أن نقول‬
‫على سبيل املثال احذف العقدة لصاحب الرقم ‪, ......50‬‬
‫يف هذه الطريقة نتبع ما يلي ‪:‬‬
‫‪ -1‬حندد العقدة املراد حذفها‪.‬‬
‫‪-2‬جنعل العقدة السابقة هلا تؤشر للعقدة التالية هلا‪.‬‬
‫‪ -3‬حنذف العقدة‬

‫احلرة‪.‬‬
‫)‪void delete_middle(node_ptr&q, int m‬‬
‫{‬
‫;‪node_ptr p,d‬‬
‫;‪p=q‬‬
‫)‪while(p->next->number!=m &&p->next->next!=NULL‬‬
‫{‬
‫;‪p=p->next‬‬
‫}‬
‫;‪d=p->next‬‬
‫;‪p->next=d->next‬‬
‫;‪delete d‬‬
‫}‬

‫نستمر بالتقدم عرب العقد إىل أن نصل إىل العقدة اليت تسبق العقدة املراد حذفها وذلك من خالل التقدم ما مل‬
‫نصل إىل قيمة البحث ‪ m‬أو إىل هناية القائمة‪NULL‬‬
‫ميثل لنا ‪ d‬العقدة املراد حذفها وذلك من خالل مساواته مع العقدة اليت يؤشر هلا حقل التأشري لـ‪ p‬ـ‬
‫إعداد األستاذ‪/‬حذيفة عبد الرحمن‬

‫‪14‬‬

‫برمجة‫تراكيب‫البيانات‬

d->next

‫ للعقدة املراد حذفها تؤشر للعقدة التالية للعقدة املراد حذفها‬p ‫جنعل العقدة السابقة‬
. d ‫بعد ذلك نقوم حبذف‬

‫وأالن نكتب برنامج متكامل للقوائم المتصلة األحادية‬
#include<iostream.h>
struct node
{
int number;
node *next;
};
typedef node *node_ptr;
// to use program easily
// prototype functions
//*******************************************
node_ptr make_new_node(node_ptr &first,int x);
void display_list(node_ptr first );
void create_nodes(node_ptr &first,int n);
void order_insert(node_ptr &first,int x);
void insert_begin(node_ptr &first);
void insert_last(node_ptr &first);
void insert_middle (node_ptr &first,int n);
void delete_first(node_ptr &first);
void delete_last (node_ptr &first);
void delete_middle(node_ptr&q,int m) ;
void edit_node (node_ptr &first,int s);
int count(node_ptr &q);
int summation(node_ptr &q);
//*****************************************
int main()
{
node_ptr first;
first=NULL;
int choose;
int n,m;
done:
cout<<"\n\n\t\t WHAT DO YOU WANT TO DO ??\n\n"
<<"\t*************************************\n"
<<"\t*\t 1- Create alist
*\n"
<<"\t*\t 2- Display list
*\n"
<<"\t*\t 3- Insert_first
*\n"
<<"\t*\t 4- Insert_end
*\n"
<<"\t*\t 5- Insert_position
*\n"
<<"\t*\t 6- Delete_first
*\n"
<<"\t*\t 7- Delete_end
*\n"
15

‫حذيفة عبد الرحمن‬/‫إعداد األستاذ‬

‫برمجة‫تراكيب‫البيانات‬

<<"\t*\t 8- Delete_position
*\n"
<<"\t*\t 9- Edit node
*\n"
<<"\t*\t 10- Numbers of Nodes
*\n"
<<"\t*\t 11- Summation nodes
*\n"
<<"\t*\t 12- Exit program
*\n"
<<"\t*************************************\n";
cin>>choose;
switch(choose)
{
case 1:
cout<<"\t Enter number of nodes to create\n";
cin>>n;
create_nodes(first,n);
goto done;
break;
case 2:
display_list (first);
goto done;
break;
case 3:
insert_begin (first);
goto done;
break;
case 4:
insert_last (first);
goto done;
break;
case 5:
cout<<"Enter position number:\n";
cin>>n;
insert_middle(first,n);
goto done;
break;
case 6:
delete_first(first);
goto done;
break;
case 7:
delete_last (first);
goto done;
break;
case 8: cout<<"\t Enter value of node to delete\n";
cin>>m;
delete_middle(first,m);
16

‫حذيفة عبد الرحمن‬/‫إعداد األستاذ‬

‫برمجة‫تراكيب‫البيانات‬

goto done;
break;
case 9:
cout<<"\t Enter number of node to edit\n";
cin>>m;
edit_node(first,m);
goto done;
break;
case 10: cout<<"Numbers of Nodes is :";
cout<<count(first)<<"\n";
goto done;
break;
case 11:
cout<<"Nodes Summation is :";
cout<<summation(first)<<"\n";
goto done;
break;
default:
char ok;
retry:
cout<<"Are you sure you want to exit [y / n ]\n";
cin>> ok;
if(ok=='n')
{
goto done;
}
else if(ok=='y')
{
}
else
{
cout<<"You are not press acorrect character ,please Retry do\n";
cout<<"Press [y] to continue or press [n] to exit program\n";
goto retry;
}
break;
}
return 0;
}

// functions details
//------------------// TO MAKE anew node
17

‫حذيفة عبد الرحمن‬/‫إعداد األستاذ‬

‫برمجة‫تراكيب‫البيانات‬

//*********************
node_ptr make_new_node(int x)
{
node_ptr p;
p=new node;
p->number =x;
p->next =NULL;
return p;
}
// TO display anodes
// **********************
void display_list(node_ptr first )
{
node_ptr p;
if(first==NULL)
cout<<"NO, nodes founds>>>";
else
{
cout<<"\t The Data in the nodes are :\n";
p=first;
while(p!=NULL)
{
cout<<"Value of node ---> ";
cout<<p->number <<endl;
p=p->next;
}
}
}
//
TO CREATE lists of nodes
//
****************************
void create_nodes(node_ptr &first,int n)
{
int x;
cout<<"\t\t Enter the data in nodes\n";
for(int i=1;i<=n;i++)
{
cout<<" Node # "<<i<<endl;
cin>>x;
order_insert(first,x);
}
}
//
Order insert
//*********************************
void order_insert(node_ptr &first,int x)
{
18

‫حذيفة عبد الرحمن‬/‫إعداد األستاذ‬

‫برمجة‫تراكيب‫البيانات‬

node_ptr p;
if(first==NULL)
{
first=make_new_node (x);
}
else if(x==first->number )
{
cout<<"\t This value in node is Exist \n";
}
else if(x<first->number )
{
p=make_new_node (x);
p->next =first;
first=p;
}
else
order_insert(first->next,x);
}
//
Insert in the Begining
// **************************
void insert_begin(node_ptr &first)
{
int x;
cout<<"Enter value in new node\n";
cin>>x;
node_ptr p;
p=make_new_node(x);
p->next=first;
first=p;
}
// Insert in the last
// ************************
void insert_last(node_ptr &first)
{
int x;
cout<<"Entr value in new node \n";
cin>>x;
node_ptr p,q;
if(first==NULL)
{
first=make_new_node (x);
}
else
{
p=first;
19

‫حذيفة عبد الرحمن‬/‫إعداد األستاذ‬

‫برمجة‫تراكيب‫البيانات‬

while(p->next!=NULL)
{
p=p->next ;
}
q=make_new_node (x);
p->next =q;
}
}
// Insert in the Position
// ************************
void insert_middle(node_ptr &first,int n)
{
int x;
cout<<"Entr value in new node \n";
cin>>x;
node_ptr p,q;
if(first==NULL)
{
first=make_new_node (x);
}
else
{
p=first;
while(p->number!=n &&p->next!=NULL)
{
p=p->next ;
}
node *q =new node;
q->number=n;
q=make_new_node (x);
q->next=p->next;
p->next =q;
}
}
//
TO delete first node
// ******************************************
void delete_first(node_ptr &first)
{
if(first==NULL)
{
cout<<"NO,nodes found .....\n";
}
else
{
node_ptr p;
20

‫حذيفة عبد الرحمن‬/‫إعداد األستاذ‬

‫برمجة‫تراكيب‫البيانات‬

p=first;
first=first->next;
delete p;
}
}
//
TO delete last Node
//
*****************
void delete_last(node_ptr &first)
{
node_ptr p,d;
p=first;
if(first==NULL)
cout<<" NO;nodes found......\n";
while(p->next->next!=NULL)
{
p=p->next;
}
d=p->next;
p->next=NULL;
delete d;
}
// To Delete Middle Node
// ************************
void delete_middle(node_ptr&q,int m)
{
node_ptr p,d;
p=q;
while(p->next->number!=m &&p->next->next!=NULL)
{
p=p->next;
}
d=p->next;
p->next=d->next;
delete d;
}
void edit_node(node_ptr &first,int s)
{
int x;
cout<<"enter value of node:\n";
cin>>x;
node_ptr p;
p=first;
while(p->number!=s && p->next!=NULL)
{
p=p->next;
21

‫حذيفة عبد الرحمن‬/‫إعداد األستاذ‬

‫برمجة‫تراكيب‫البيانات‬

}
p->number=x;
}
int count(node_ptr &q)
{
node_ptr p;
p=q;
int count=0;
while(p!=NULL)
{
count++;
p=p->next;
}
return count;
}
int summation(node_ptr&q)
{
node_ptr p;
p=q;
int sum=0;
while(p!=NULL)
{
sum+=p->number;
p=p->next;
}
return sum;
}

22

‫حذيفة عبد الرحمن‬/‫إعداد األستاذ‬