فرز التحديد

في علوم الحاسوب ، يُعدّ فرز التحديد خوارزمية فرز مقارنة موضعية . يتميز بتعقيد زمني قدره O ( ) ، مما يجعله غير فعال مع القوائم الكبيرة، وعادةً ما يكون أداؤه أسوأ من فرز الإدراج المماثل . يُعرف فرز التحديد ببساطته، ويتمتع بمزايا أداء على الخوارزميات الأكثر تعقيدًا في بعض الحالات، لا سيما عندما تكون الذاكرة الإضافية محدودة.

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

إن كفاءة الوقت لفرز الاختيار هي تربيعية، لذلك هناك عدد من تقنيات الفرز التي تتمتع بتعقيد زمني أفضل من فرز الاختيار.

مثال

فيما يلي مثال على خوارزمية الفرز هذه التي تقوم بفرز خمسة عناصر:

قائمة فرعية مرتبةقائمة فرعية غير مرتبةأصغر عنصر في قائمة غير مرتبة
()(12، 25، 64، 11، 22)11
(11)(25، 64، 12، 22)12
(11، 12)(25، 64، 22)22
(11، 12، 22)(25، 64)25
(11، 12، 22، 25)(64)64
(11، 12، 22، 25، 64)()
رسوم متحركة لفرز العناصر. الأحمر يمثل العنصر الأدنى الحالي. الأصفر يمثل القائمة المرتبة. الأزرق يمثل العنصر الحالي.

(لم يظهر أي تغيير في هذين السطرين الأخيرين لأن الرقمين الأخيرين كانا بالترتيب بالفعل.)

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

arr[] = 64 25 12 22 11 // إيجاد أصغر عنصر في arr[0...4] // وضعها في البداية <11> 25 12 22 64 // إيجاد أصغر عنصر في arr[1...4] // ضعها في بداية arr[1...4] 11 <12> 25 22 64 // إيجاد أصغر عنصر في arr[2...4] // وضعها في بداية arr[2...4] 11 12 <22> 25 64 // إيجاد أصغر عنصر في arr[3...4] // ضعها في بداية arr[3...4] 11 12 22 <25> 64 

التطبيقات

فيما يلي تطبيق مكتوب بلغة C.

void swap ( int * x , int * y ) { int temp = * x ; * x = * y ; * y = temp ; }// دالة فرز التحديد void selectionSort ( int a [], int length ) { // المرور على المصفوفة بأكملها (باستثناء العنصر الأخير) for ( int i = 0 ; i < length - 1 ; ++ i ) { int jMin = i ; // افتراض أن الموضع الحالي هو الحد الأدنى// البحث عن أصغر عنصر في الجزء غير المرتب for ( int j = i + 1 ; j < length ; ++ j ) { if ( a [ j ] < a [ jMin ]) { // تم العثور على عنصر أصغر jMin = j ; // تحديث فهرس العنصر الأصغر } }// قم بالتبديل فقط إذا تم العثور على عنصر أصغر إذا ( jMin != i ) { swap ( &a a [ i ], &a a [ jMin ]); } } }

تعقيد

لا يُعدّ تحليل خوارزمية فرز التحديد صعبًا مقارنةً بخوارزميات الفرز الأخرى، إذ لا تعتمد أيٌّ من حلقاتها على البيانات الموجودة في المصفوفة. ويتطلب اختيار العنصر الأدنى مسحًا.ن{\displaystyle n}العناصر (أخذن-1{\displaystyle n-1}ثم يتم استبداله بالموضع الأول. يتطلب إيجاد العنصر الأدنى التالي مسح العناصر المتبقيةن-1{\displaystyle n-1}العناصر (أخذن-2{\displaystyle n-2}المقارنات) وهكذا. لذلك، فإن العدد الإجمالي للمقارنات هو

(ن-1)+(ن-2)++1=أنا=1ن-1أنا{\displaystyle (n-1)+(n-2)+\dots +1=\sum _{i=1}^{n-1}i}

باستخدام المتتابعة الحسابية ،

أنا=1ن-1أنا=(ن-1)+12(ن-1)=12ن(ن-1)=12(ن2-ن){\displaystyle \sum _{i=1}^{n-1}i={\frac {(n-1)+1}{2}}(n-1)={\frac {1}{2}}n(n-1)={\frac {1}{2}}(n^{2}-n)}

وهو أمر معقديا(ن2){\displaystyle O(n^{2})}من حيث عدد المقارنات.

مقارنة بخوارزميات الفرز الأخرى

من بين خوارزميات الفرز التربيعي (خوارزميات الفرز ذات الحالة المتوسطة البسيطة Θ( ) )، يتفوق فرز الاختيار دائمًا تقريبًا على فرز الفقاعات وفرز الأقزام . يشبه فرز الإدراج إلى حد كبير فرز الاختيار ، حيث أنه بعد التكرار رقم k ، يكون أولك{\displaystyle k}تكون عناصر المصفوفة مرتبة ترتيبًا تصاعديًا. وتكمن ميزة خوارزمية فرز الإدراج في أنها تفحص فقط العدد اللازم من العناصر لوضعها في المصفوفة المطلوبة.ك+1{\displaystyle k+1}بينما يجب على فرز التحديد مسح جميع العناصر المتبقية للعثور على العنصر الأول.ك+1{\displaystyle k+1}العنصر الأول.

تُظهر حسابات بسيطة أن فرز الإدراج يُجري عادةً نصف عدد المقارنات التي يُجريها فرز التحديد، مع أنه قد يُجري نفس العدد أو عددًا أقل بكثير اعتمادًا على ترتيب المصفوفة قبل الفرز. يُمكن اعتبار هذا ميزةً لبعض التطبيقات الآنية ، حيث يُؤدي فرز التحديد نفس الأداء بغض النظر عن ترتيب المصفوفة، بينما قد يختلف وقت تشغيل فرز الإدراج اختلافًا كبيرًا. مع ذلك، غالبًا ما تكون هذه ميزةً لفرز الإدراج، إذ يعمل بكفاءة أعلى بكثير إذا كانت المصفوفة مُرتبةً بالفعل أو "شبه مُرتبة".

بينما يُفضّل فرز التحديد على فرز الإدراج من حيث عدد عمليات الكتابة (ن-1{\displaystyle n-1}المقايضات مقابل ما يصل إلىن(ن-1)/2{\displaystyle n(n-1)/2}(مع عمليات تبديل، حيث تتضمن كل عملية تبديل عمليتي كتابة)، يُعادل هذا ضعف الحد الأدنى النظري الذي تحققه خوارزمية فرز الدورة ، والتي تُجري على الأكثر n عملية كتابة. قد يكون هذا الأمر بالغ الأهمية إذا كانت عمليات الكتابة أكثر تكلفة بكثير من عمليات القراءة، كما هو الحال مع ذاكرة EEPROM أو ذاكرة الفلاش ، حيث تُقلل كل عملية كتابة من عمر الذاكرة.

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

وأخيرًا، يتفوق فرز التحديد بشكل كبير على المصفوفات الأكبر حجمًا بواسطةΘ(نسجلن){\displaystyle \Theta (n\log n)}تُعدّ خوارزميات فرق تسد، مثل فرز الدمج ، من بين الخوارزميات التي تُحسّن الأداء . مع ذلك، فإنّ فرز الإدراج أو فرز التحديد أسرع عادةً للمصفوفات الصغيرة (أي أقل من 10-20 عنصرًا). ومن التحسينات المفيدة عمليًا للخوارزميات التكرارية التحوّل إلى فرز الإدراج أو فرز التحديد للقوائم الفرعية "الصغيرة بما يكفي".

المتغيرات

وُصفت خوارزمية فرز الكومة بأنها "ليست سوى تطبيق لخوارزمية فرز الاختيار باستخدام بنية البيانات المناسبة ". [ 1 ] وهي تُحسّن الخوارزمية الأساسية بشكل كبير من خلال استخدام بنية بيانات الكومة الضمنية للعثور على كل عنصر أدنى وإزالته.Θ(سجلن){\displaystyle \Theta (\log n)}الوقت، بدلاً من فرز الاختيار العاديΘ(ن){\displaystyle \Theta (n)}حلقة داخلية، مما يقلل من إجمالي وقت التشغيل إلىΘ(نسجلن){\displaystyle \Theta (n\log n)}.

يُحدد نوع ثنائي الاتجاه من فرز الاختيار (يُسمى فرز الاختيار المزدوج أو فرز الكوكتيل لتشابهه مع فرز خلط الكوكتيل ) القيمتين الدنيا والقصوى في القائمة في كل دورة. يتطلب هذا النوع ثلاث مقارنات لكل عنصرين (حيث تتم مقارنة عنصرين، ثم تتم مقارنة العنصر الأكبر بالقيمة القصوى والعنصر الأصغر بالقيمة الدنيا) بدلاً من مقارنة واحدة لكل عنصر في فرز الاختيار العادي، ولكنه يتطلب نصف عدد الدورات فقط، أي توفير صافٍ بنسبة 25%.

يمكن تطبيق فرز التحديد كفرز مستقر إذا تم، بدلاً من التبديل في الخطوة الثانية، إدخال القيمة الدنيا في الموضع الأول وإزاحة القيم الوسيطة للأعلى. ومع ذلك، يتطلب هذا التعديل إما بنية بيانات تدعم عمليات الإدخال أو الحذف بكفاءة، مثل القائمة المرتبطة، أو أنه يؤدي إلى أداءΘ(ن2){\displaystyle \Theta (n^{2})}يكتب.

في خوارزمية فرز البنغو ، تُفرز العناصر من خلال البحث المتكرر بين العناصر المتبقية للعثور على القيمة الأكبر، ثم نقل جميع العناصر التي تحمل هذه القيمة إلى موقعها النهائي. [ 2 ] ومثل فرز العد ، تُعد هذه الخوارزمية فعالة في حال وجود العديد من القيم المكررة: ففرز التحديد يمر مرة واحدة على العناصر المتبقية لكل عنصر يتم نقله، بينما يمر فرز البنغو مرة واحدة لكل قيمة . بعد المرور الأولي للعثور على القيمة الأكبر، تنقل المرورات اللاحقة كل عنصر يحمل هذه القيمة إلى موقعه النهائي مع البحث عن القيمة التالية، كما هو موضح في الشفرة الزائفة التالية (المصفوفات تبدأ من الصفر، وحلقة التكرار تتضمن الحدين العلوي والسفلي، كما في لغة باسكال ):

بينغو ( المصفوفة أ ){ يقوم هذا الإجراء بالفرز بترتيب تصاعدي عن طريق  نقل العناصر ذات القيم القصوى بشكل متكرر إلى النهاية. } ابدأ last := length ( A ) - 1 ;{ كُتبت الدورة الأولى لتكون مشابهة جدًا  للدورات اللاحقة، ولكن بدون تبديل. } nextMax := A [ last ] ; for i := last - 1 downto 0 do if A [ i ] > nextMax then nextMax := A [ i ] ; while ( last > 0 ) and ( A [ last ] = nextMax ) do last := last - 1 ;بينما last > ابدأ { تبحث كل حلقة رئيسية عن nextMax الجديد مع  تبديل العناصر التي تساوي prevMax في مكانها. } prevMax := nextMax ; nextMax := A [ last ] ; for i := last - 1 downto 0 do if A [ i ] > nextMax then if A [ i ] <> prevMax then nextMax := A [ i ] ; else begin swap ( A [ i ] , A [ last ]) ; last := last - 1 ; end while ( last > 0 ) and ( A [ last ] = nextMax ) do last := last - 1 ; end ; end ;

وبالتالي، إذا كان هناك في المتوسط ​​أكثر من عنصرين لهما نفس القيمة، فمن المتوقع أن يكون فرز البنغو أسرع لأنه ينفذ الحلقة الداخلية مرات أقل من فرز التحديد.

انظر أيضاً

مراجع

  1. سكينا، ستيفن (2008). "البحث والفرز". دليل تصميم الخوارزميات (  الطبعة الثالثة). سبرينغر. ص  116. doi : 10.1007/978-3-030-54256-6_4 . ISBN 978-3-030-54255-9إن الاسم الذي يطلق عادةً على هذه الخوارزمية، وهو heapsort ، يحجب حقيقة أن الخوارزمية ليست سوى تطبيق لفرز التحديد باستخدام بنية البيانات الصحيحة.
  2. تتضمن هذه المقالة موادًا متاحة للعموم من بول إي. بلاك. "فرز البنغو" . قاموس الخوارزميات وهياكل البيانات . المعهد الوطني للمعايير والتكنولوجيا (NIST) .المجال العام 
  • دونالد كنوث . فن برمجة الحاسوب ، المجلد 3: الفرز والبحث ، الطبعة الثالثة. أديسون-ويسلي، 1997. ISBN 0-201-89685-0الصفحات 138-141 من القسم 5.2.3: الفرز حسب التحديد.
  • أناني ليفيتين. مقدمة في تصميم وتحليل الخوارزميات ، الطبعة الثانية. ISBN 0-321-35828-7القسم 3.1: فرز الاختيار، الصفحات 98-100.
  • روبرت سيدجويك . الخوارزميات في لغة C++، الأجزاء 1-4: الأساسيات، هياكل البيانات، الفرز، البحث: الأساسيات، هياكل البيانات، الفرز، البحث، الأجزاء 1-4 ، الطبعة الثانية. أديسون-ويسلي لونجمان، 1998. ISBN 0-201-35088-2الصفحات 273-274
  • خوارزميات الفرز المتحركة: فرز التحديد في أرشيف الإنترنت (تمت أرشفته في 7 مارس 2015) - عرض توضيحي رسومي