كيفية استخدام C ++ Priority_queue؟

How Use C Priority_queue



في C ++ ، قائمة الانتظار هي بنية بيانات قائمة حيث يكون العنصر الأول الذي سيتم وضعه في القائمة هو العنصر الأول الذي يجب إزالته ، عندما تتم الإزالة. تتشابه قائمة انتظار الأولوية في C ++ ، ولكن بها بعض الطلبات ؛ هو العنصر ذو القيمة الأكبر الذي تتم إزالته أولاً. لا يزال من الممكن تكوين قائمة انتظار الأولوية بحيث تتم إزالة العنصر ذي القيمة الأقل أولاً. يجب أن تحتوي أي قائمة انتظار على الامتداد يدفع() وظيفة و البوب ​​() وظيفة. ال يدفع() تضيف الوظيفة عنصرًا جديدًا في الخلف. بالنسبة لقائمة الانتظار العادية ، فإن ملف البوب ​​() تعمل الوظيفة على إزالة العنصر الأول الذي تم دفعه على الإطلاق. لقائمة انتظار الأولوية ، فإن البوب ​​() تعمل الوظيفة على إزالة العنصر ذي الأولوية القصوى ، والذي يمكن أن يكون الأكبر أو الأصغر ، اعتمادًا على نظام الترتيب.

من أجل استخدام C ++ priority_queue ، يجب أن يبدأ البرنامج برمز مثل:







#يشمل
#يشمل
استخدام مساحة الاسمساعات؛

يتضمن مكتبة قائمة الانتظار في البرنامج.



من أجل مواصلة القراءة ، يجب أن يكون لدى القارئ معرفة أساسية بـ C ++.



محتوى المادة

البناء الأساسي

يجب إنشاء بنية البيانات أولاً قبل استخدامها. يعني البناء هنا إنشاء مثيل لكائن من فئة قائمة الانتظار في المكتبة. يجب أن يكون لكائن قائمة الانتظار اسمًا أطلقه عليه المبرمج. أبسط بناء جملة لإنشاء قائمة انتظار ذات أولوية هو:





طابور الأولوية<نوع>اسم الطابور؛

باستخدام بناء الجملة هذا ، تتم إزالة أكبر قيمة أولاً. مثال على إنشاء مثيل هو:

طابور الأولوية<int>ص؛

أو



طابور الأولوية<شار>ص؛

المتجه و deque هما هيكلان للبيانات في C ++. يمكن إنشاء priority_queue مع أي منهما. بناء الجملة لإنشاء قائمة انتظار أولوية من بنية المتجه هو:

طابور الأولوية<اكتب ، ناقل<نفس النوعيه>، قارن>ص؛

مثال على هذا إنشاء مثيل هو:

طابور الأولوية<int، المتجه<int>، أقل<int> >ص؛

لاحظ الفجوة بين> و> في نهاية الإعلان. هذا لمنع الخلط مع >>. كود المقارنة الافتراضي أقل ، مما يعني أن القيمة الأكبر ، وليس بالضرورة القيمة الأولى ، ستتم إزالتها أولاً. لذلك ، يمكن ببساطة كتابة بيان الخلق على النحو التالي:

طابور الأولوية<int، المتجه<int> >ص؛

إذا تمت إزالة أقل قيمة أولاً ، فيجب أن تكون العبارة:

طابور الأولوية<int، المتجه<int>، أكبر<int> >ص؛

وظائف الأعضاء الهامة

وظيفة الدفع ()
تدفع هذه الدالة قيمة ، وهي وسيطتها ، إلى قيمة priority_queue. يعود الفراغ. يوضح الكود التالي هذا:

طابور الأولوية<int>ص؛

ص.يدفع(10)؛
ص.يدفع(30)؛
ص.يدفع(عشرين)؛
ص.يدفع(خمسون)؛
ص.يدفع(40)؛

لقد استقبلت Prior_queue 5 قيم عدد صحيح بالترتيب 10 ، 30 ، 20 ، 50 ، 40. إذا تم إخراج كل هذه العناصر من قائمة انتظار الأولوية ، فستظهر بترتيب 50 ، 40 ، 30 ، 20 ، 10.

وظيفة البوب
تزيل هذه الوظيفة من priority_queue القيمة ذات الأولوية القصوى. إذا كانت شفرة المقارنة أكبر ، فستزيل العنصر ذي القيمة الأصغر. إذا تم استدعاؤه مرة أخرى ، فإنه يزيل العنصر التالي بأقل قيمة للباقي ؛ مرة أخرى ، فإنه يزيل أصغر قيمة حالية تالية ، وهكذا. يعود الفراغ. يوضح الكود التالي هذا:

طابور الأولوية<شار، المتجه<شار>، أكبر<int> >ص؛
ص.يدفع('إلى')؛ص.يدفع('ج')؛ص.يدفع('ب')؛ص.يدفع('و')؛ص.يدفع('د')؛

لاحظ أنه من أجل استدعاء وظيفة عضو ، يجب أن يتبع اسم الكائن نقطة ، ثم الوظيفة.

الوظيفة العلوية ()
ال البوب ​​() تعمل الوظيفة على إزالة القيمة التالية ذات الأولوية القصوى ، ولكنها لا تعيدها ، مثل البوب ​​() هي وظيفة باطلة. استخدم ال أعلى() تعمل من أجل معرفة قيمة الأولوية القصوى التي يجب إزالتها بعد ذلك. ال أعلى() تُرجع الدالة نسخة من القيمة ذات الأولوية القصوى في priority_queue. يوضح هذا الكود التالي ، حيث تكون القيمة التالية ذات الأولوية القصوى هي أقل قيمة

طابور الأولوية<شار، المتجه<شار>، أكبر<int> >ص؛
ص.يدفع('إلى')؛ص.يدفع('ج')؛ص.يدفع('ب')؛ص.يدفع('و')؛ص.يدفع('د')؛
شارالفصل 1=ص.أعلى()؛ص.البوب()؛
شارالفصل 2=ص.أعلى()؛ص.البوب()؛
شارch3=ص.أعلى()؛ص.البوب()؛
شارالفصل 4=ص.أعلى()؛ص.البوب()؛
شارالفصل 5=ص.أعلى()؛ص.البوب()؛

كلفة<<الفصل 1<<'<<الفصل 2<<'<<ch3<<'<<الفصل 4<<'<<الفصل 5<<'ن'؛

الناتج هو 'أ' 'ب' 'ج' 'د' 'ه'.

الدالة الفارغة ()
إذا كان المبرمج يستخدم ملف أعلى() تعمل على priority_queue فارغًا ، بعد نجاح عملية التجميع ، سيتلقى رسالة خطأ مثل:

خطأ تجزئة(الأساسية ملقاة)

لذلك ، تحقق دائمًا مما إذا كانت قائمة انتظار الأولوية ليست فارغة قبل استخدام ملف أعلى() وظيفة. ال فارغة() العضو تعيد منطقيًا ، صحيحًا ، إذا كانت قائمة الانتظار فارغة ، وخطأ إذا لم تكن قائمة الانتظار فارغة. يوضح الكود التالي هذا:

طابور الأولوية<int>ص؛
intأنا 1= 10؛ inti2= 30؛ inti3= عشرين؛ inti4= خمسون؛ intمعالج i5= 40؛
ص.يدفع(أنا 1)؛ص.يدفع(i2)؛ص.يدفع(i3)؛ص.يدفع(i4)؛ص.يدفع(معالج i5)؛

في حين(!ص.فارغة())
{
كلفة <<ص.أعلى() << '؛
ص.البوب()؛
}
كلفة << 'ن'؛

وظائف قائمة الانتظار الأخرى ذات الأولوية

وظيفة الحجم ()
ترجع هذه الدالة طول قائمة انتظار الأولوية ، كما يوضح الكود التالي:

طابور الأولوية<int>ص؛
intأنا 1= 10؛ inti2= 30؛ inti3= عشرين؛ inti4= خمسون؛ intمعالج i5= 40؛
ص.يدفع(أنا 1)؛ص.يدفع(i2)؛ص.يدفع(i3)؛ص.يدفع(i4)؛ص.يدفع(معالج i5)؛

intلين=ص.بحجم()؛
كلفة <<لين<< 'ن'؛

الخرج هو 5.

وظيفة المبادلة ()
إذا كان هناك نوعان من Prior_queues من نفس النوع والحجم ، فيمكن استبدالهما بهذه الوظيفة ، كما يوضح الكود التالي:

طابور الأولوية<int>pq1؛
intأنا 1= 10؛ inti2= 30؛ inti3= عشرين؛ inti4= خمسون؛ intمعالج i5= 40؛
pq1.يدفع(أنا 1)؛pq1.يدفع(i2)؛pq1.يدفع(i3)؛pq1.يدفع(i4)؛pq1.يدفع(معالج i5)؛

طابور الأولوية<int>pqA؛
intit1= 1؛ intit2= 3؛ intit3= 2؛ intit4= 5؛ intit5= 4؛
pqA.يدفع(it1)؛pqA.يدفع(it2)؛pqA.يدفع(it3)؛pqA.يدفع(it4)؛pqA.يدفع(it5)؛

pq1.مبادلة، مقايضة(pqA)؛

في حين(!pq1.فارغة())
{
كلفة <<pq1.أعلى() << '؛
pq1.البوب()؛
} كلفة<<'ن'؛

في حين(!pqA.فارغة())
{
كلفة <<pqA.أعلى() << '؛
pqA.البوب()؛
} كلفة<<'ن'؛

الخرج هو:

& emsp؛ 5 & emsp؛ 4 & emsp؛ 3 & emsp؛ 2 & emsp؛ 1
& emsp؛ 50 & emsp؛ 40 & emsp؛ 30 & emsp؛ 20 & emsp؛ 10

المكان () Fuction
ال emplace () وظيفة مشابهة لوظيفة الدفع. يوضح الكود التالي هذا:

طابور الأولوية<int>pq1؛
intأنا 1= 10؛ inti2= 30؛ inti3= عشرين؛ inti4= خمسون؛ intمعالج i5= 40؛
pq1.مكان(أنا 1)؛pq1.مكان(i2)؛pq1.مكان(i3)؛pq1.مكان(i4)؛pq1.مكان(معالج i5)؛

في حين(!pq1.فارغة())
{
كلفة <<pq1.أعلى() << '؛
pq1.البوب()؛
} كلفة<<'ن'؛

الخرج هو:

50 40 30 20 10

بيانات السلسلة

عند مقارنة السلاسل ، يجب استخدام فئة السلسلة وليس الاستخدام المباشر للسلسلة الحرفية لأنها ستقارن المؤشرات وليس السلاسل الفعلية. يوضح الكود التالي كيفية استخدام فئة السلسلة:

#يشمل
طابور الأولوية<سلسلة>pq1؛
سلسلة s1=سلسلة('قلم')، s2=سلسلة('قلم')، s3=سلسلة('كتاب التمارين')، 4 س=سلسلة('كتاب نصي')، s5=سلسلة('مسطرة')؛

pq1.يدفع(ق 1)؛pq1.يدفع(s2)؛pq1.يدفع(s3)؛pq1.يدفع(4 س)؛pq1.يدفع(s5)؛
في حين(!pq1.فارغة())
{
كلفة <<pq1.أعلى() << '؛
pq1.البوب()؛
} كلفة<<'ن'؛

الخرج هو:

& emsp؛ كتاب نصي & emsp؛ مسطرة & emsp؛ قلم رصاص & emsp؛ قلم & emsp؛ كتاب تمرين

إنشاءات قائمة انتظار أخرى ذات أولوية

إنشاء صريح من متجه
يمكن إنشاء قائمة انتظار ذات أولوية بشكل صريح من متجه كما يوضح الكود التالي:

#يشمل
المتجه<int>vtr= {10و30وعشرينوخمسونو40}؛

طابور الأولوية<int>ص(vtr.يبدأ()، vtr.نهاية())؛

في حين(!ص.فارغة())
{
كلفة <<ص.أعلى() << '؛
ص.البوب()؛
} كلفة<<'ن'؛

الناتج هو: 50 40 30 20 10. هذه المرة ، يجب أيضًا تضمين رأس المتجه. تأخذ الوسائط الخاصة بوظيفة المُنشئ مؤشري البداية والنهاية للمتجه. يجب أن يكون نوع البيانات للمتجه ونوع البيانات لـ priority_queue هو نفسه.

من أجل جعل الأولوية الأقل قيمة ، سيكون إعلان المُنشئ:

طابور الأولوية<int، المتجه<int>، أكبر>int> >ص(vtr.يبدأ()، vtr.نهاية())؛

إنشاء صريح من مصفوفة
يمكن إنشاء قائمة انتظار ذات أولوية بشكل صريح من مصفوفة كما يوضح الكود التالي:

intarr[] = {10و30وعشرينوخمسونو40}؛

طابور الأولوية<int>ص(آر ، آر+5)؛

في حين(!ص.فارغة())
{
كلفة <<ص.أعلى() << '؛
ص.البوب()؛
} كلفة<<'ن'؛

الناتج هو: 50 40 30 20 10. تأخذ الوسيطات الخاصة بوظيفة المُنشئ مؤشري البداية والنهاية للمصفوفة. تقوم arr بإرجاع مؤشر البداية ، وترجع arr + 5 المؤشر بعد المصفوفة مباشرة ، و 5 هي حجم المصفوفة. يجب أن يكون نوع البيانات للمصفوفة ونوع البيانات لـ priority_queue متماثلين.

من أجل جعل الأولوية الأقل قيمة ، سيكون إعلان المُنشئ:

طابور الأولوية<int، المتجه<int>، أكبر<int> >ص(آر ، آر+5)؛

ملاحظة: في لغة C ++ ، يُطلق على priority_queue اسم محول ، وليس مجرد حاوية.

كود المقارنة المخصص

إن وجود جميع القيم في قائمة انتظار الأولوية تصاعديًا أو تنازليًا ليس هو الخيار الوحيد لقائمة انتظار الأولوية. على سبيل المثال ، قائمة 11 عددًا صحيحًا لأقصى كومة هي:

88 ، 86 ، 87 ، 84 ، 82 ، 79 ، 74 ، 80 ، 81 ، ، 64 ، 69

أعلى قيمة هي 88. يليها رقمان: 86 و 87 ، وهما أقل من 88. أما باقي الأرقام فهي أقل من هذه الأرقام الثلاثة ، ولكن ليس بالترتيب الحقيقي. توجد خليتان فارغتان في القائمة. الأرقام 84 و 82 أقل من 86. الأعداد 79 و 74 أقل من 87. الأعداد 80 و 81 أقل من 84. الرقمان 64 و 69 أقل من 79.

يتبع موضع الأرقام معايير max-heap - انظر لاحقًا. من أجل توفير مثل هذا المخطط لـ priority_queue ، يجب على المبرمج تقديم كود المقارنة الخاص به - انظر لاحقًا.

استنتاج

تعد C ++ priority_queue قائمة انتظار أول من يخرج أولاً. وظيفة العضو ، يدفع()، يضيف قيمة جديدة إلى قائمة الانتظار. وظيفة العضو ، أعلى()، يقرأ أعلى قيمة في قائمة الانتظار. وظيفة العضو ، البوب ​​() ، يزيل دون إرجاع أعلى قيمة لقائمة الانتظار. وظيفة العضو ، فارغة()، يتحقق ما إذا كانت قائمة الانتظار فارغة. ومع ذلك ، فإن priority_queue يختلف عن قائمة الانتظار ، حيث أنه يتبع بعض خوارزمية الأولوية. يمكن أن يكون أعظم ، من الأول إلى الأخير ، أو على الأقل ، من الأول إلى الأخير. يمكن أيضًا تحديد المعايير (الخوارزمية) بواسطة المبرمج.