فرز الاختيار
آخر تحديث
يقسّم فرز الاختيار المصفوفة إلى منطقة مرتبة على اليسار ومنطقة غير مرتبة على اليمين. في كل تمريرة يمسح المنطقة غير المرتبة للعثور على أصغر عنصر، ثم يبدّله إلى أول موضع غير مرتب - فتنمو المنطقة المرتبة بمقدار واحد. اضغط على التشغيل في الأعلى لمشاهدة المسح والتبديل، أو تنقّل مقارنةً تلو الأخرى.
يجري فرز الاختيار دائمًا العدد نفسه من المقارنات بغضّ النظر عن المدخلات، لكنه ينفّذ على الأكثر n-1 من عمليات التبديل - أقل بكثير من فرز الفقاعة - وهو ما يهمّ عندما تكون عمليات الكتابة مكلفة.
التعقيد الزمني والمكاني
| الحالة | التعقيد | ملاحظات |
|---|---|---|
| أفضل حالة | O(n²) | تُجرى المقارنات حتى لو كانت المصفوفة مرتبة |
| الحالة المتوسطة | O(n²) | ترتيب عشوائي |
| أسوأ حالة | O(n²) | ترتيب عكسي |
| المساحة | O(1) | في المكان |
| مستقرة | لا | قد تعيد عمليات التبديل ترتيب العناصر المتساوية |
خطوة بخطوة
| الخطوة | ما الذي يحدث |
|---|---|
| 1 | اعتبر المصفوفة بأكملها غير مرتبة. |
| 2 | امسح المنطقة غير المرتبة للعثور على العنصر الأصغر. |
| 3 | بدّل ذلك العنصر الأصغر إلى أول موضع غير مرتب. |
| 4 | حرّك الحد خطوةً واحدة إلى اليمين (أصبح ذلك الموضع مرتبًا الآن). |
| 5 | كرّر حتى يتبقى عنصر واحد فقط غير مرتب. |
مثال محلول
فرز [5, 2, 4, 1]:
| التمريرة | المصفوفة | الإجراء |
|---|---|---|
| البداية | [5, 2, 4, 1] | المصفوفة بأكملها غير مرتبة. |
| 1 | [1, 2, 4, 5] | امسح [5, 2, 4, 1]، الأصغر هو 1 عند الفهرس 3؛ بدّله مع الفهرس 0. |
| 2 | [1, 2, 4, 5] | امسح [2, 4, 5]، الأصغر هو 2 الموجود أصلًا عند الفهرس 1؛ يُبدّل مع نفسه. |
| 3 | [1, 2, 4, 5] | امسح [4, 5]، الأصغر هو 4 الموجود أصلًا عند الفهرس 2؛ لا حاجة لأي نقل. |
| انتهى | [1, 2, 4, 5] | لم يتبقّ سوى 5، فهو بالفعل في مكانه. |
متى تستخدم فرز الاختيار
| استخدمه عندما | تجنّبه عندما |
|---|---|
تكون عمليات الكتابة مكلفة - فهو ينفّذ على الأكثر n-1 من عمليات التبديل. | تكون المصفوفة كبيرة - إذ تهيمن مقارنات O(n²). |
| تحتاج إلى فرز بسيط وسهل التنفيذ في المكان. | تحتاج إلى فرز مستقر يحافظ على ترتيب المفاتيح المتساوية. |
تكون الذاكرة محدودة - فهو يستخدم O(1) فقط من المساحة الإضافية. | تكون البيانات شبه مرتبة - إذ لا يمكنه الانتهاء مبكرًا مثل فرز الإدراج. |
| تكون مجموعة البيانات صغيرة جدًا ويهمّ الأداء المتوقّع. | يهمّ معدل الإنتاجية - إذ إن خوارزميات O(n log n) مثل الفرز السريع أسرع بكثير. |
كود Selection Sort
تنفيذ نظيف وقابل للتشغيل لخوارزمية Selection Sort بلغات Python, JavaScript, Java, C++, C. اختر لغة، وانسخ الكود، أو افتحه محمّلًا مسبقًا في ساحة تجربة Coddy.
كود Selection Sort بلغة Python
1def selection_sort(a):2 n = len(a)3 for i in range(n - 1):4 # Find the smallest element in the unsorted tail5 min_idx = i6 for j in range(i + 1, n):7 if a[j] < a[min_idx]:8 min_idx = j9 a[i], a[min_idx] = a[min_idx], a[i]10 return a11
12
13nums = [64, 25, 12, 22, 11]14print("Before:", nums)15selection_sort(nums)16print("After: ", nums)كود Selection Sort بلغة JavaScript
1function selectionSort(a) {2 for (let i = 0; i < a.length - 1; i++) {3 let min = i;4 // Find the smallest element in the unsorted tail5 for (let j = i + 1; j < a.length; j++) {6 if (a[j] < a[min]) min = j;7 }8 if (min !== i) [a[i], a[min]] = [a[min], a[i]];9 }10 return a;11}12
13const data = [5, 2, 9, 1, 7, 3];14console.log("Before:", data);15console.log("Sorted:", selectionSort([...data]));كود Selection Sort بلغة Java
1import java.util.Arrays;2
3public class Main {4 static void selectionSort(int[] arr) {5 for (int i = 0; i < arr.length - 1; i++) {6 int minIndex = i;7 // Find the smallest value in the unsorted part8 for (int j = i + 1; j < arr.length; j++) {9 if (arr[j] < arr[minIndex]) minIndex = j;10 }11 int tmp = arr[i];12 arr[i] = arr[minIndex];13 arr[minIndex] = tmp;14 }15 }16
17 public static void main(String[] args) {18 int[] arr = {29, 10, 14, 37, 13, 5};19 System.out.println("Before: " + Arrays.toString(arr));20 selectionSort(arr);21 System.out.println("After: " + Arrays.toString(arr));22 }23}كود Selection Sort بلغة C++
1#include <iostream>2#include <utility>3#include <vector>4
5void printVec(const std::vector<int>& a) {6 for (int x : a) std::cout << x << " ";7 std::cout << "\n";8}9
10void selectionSort(std::vector<int>& a) {11 for (size_t i = 0; i + 1 < a.size(); ++i) {12 // Find the smallest element in the unsorted suffix13 size_t minIdx = i;14 for (size_t j = i + 1; j < a.size(); ++j) {15 if (a[j] < a[minIdx]) minIdx = j;16 }17 std::swap(a[i], a[minIdx]);18 }19}20
21int main() {22 std::vector<int> data = {29, 10, 14, 37, 13, 5};23 std::cout << "Before: ";24 printVec(data);25 selectionSort(data);26 std::cout << "After: ";27 printVec(data);28 return 0;29}كود Selection Sort بلغة C
1#include <stdio.h>2
3void printArr(const int a[], int n) {4 for (int i = 0; i < n; i++) printf("%d ", a[i]);5 printf("\n");6}7
8void selectionSort(int a[], int n) {9 for (int i = 0; i < n - 1; i++) {10 // Find the smallest element in the unsorted suffix11 int minIdx = i;12 for (int j = i + 1; j < n; j++) {13 if (a[j] < a[minIdx]) minIdx = j;14 }15 int tmp = a[i];16 a[i] = a[minIdx];17 a[minIdx] = tmp;18 }19}20
21int main(void) {22 int data[] = {29, 10, 14, 37, 13, 5};23 int n = sizeof(data) / sizeof(data[0]);24 printf("Before: ");25 printArr(data, n);26 selectionSort(data, n);27 printf("After: ");28 printArr(data, n);29 return 0;30}أسئلة شائعة حول فرز الاختيار
ما هو التعقيد الزمني لفرز الاختيار؟
O(n²) في جميع الحالات - الأفضل والمتوسط والأسوأ - لأنه يمسح دائمًا المنطقة غير المرتبة بأكملها للعثور على كل عنصر أصغر. ويستخدم O(1) من المساحة الإضافية.هل فرز الاختيار مستقر؟
متى يكون فرز الاختيار مفيدًا؟
n-1 من عمليات التبديل - وهو أقل عدد ممكن لفرز قائم على المقارنة يقوم بنقل العناصر.ما الفرق بين فرز الاختيار وفرز الفقاعة؟
O(n²)، لكن فرز الاختيار يجري على الأكثر n-1 من عمليات التبديل بينما قد يجري فرز الفقاعة حتى O(n²) منها. كما يمكن لفرز الفقاعة اكتشاف مصفوفة مرتبة مسبقًا والتوقف مبكرًا، في حين ينفّذ فرز الاختيار دائمًا جميع التمريرات.هل ينبغي أن أستخدم فرز الاختيار أم فرز الإدراج؟
O(n) على البيانات شبه المرتبة، وأسرع في المتوسط. اختر فرز الاختيار فقط عندما يكون تقليل عدد عمليات الكتابة هو الأولوية، لأنه يضمن على الأكثر n-1 من عمليات التبديل.لماذا يعمل فرز الاختيار دائمًا بـ O(n²) حتى على مصفوفة مرتبة؟
O(n²) - على عكس فرز الإدراج أو الفقاعة اللذين يمكنهما التوقف مبكرًا.