الفرز الدوري عبارة عن خوارزمية فرز غير مستقرة في مكانها، وهي مفيدة بشكل خاص عند فرز المصفوفات التي تحتوي على عناصر ذات نطاق صغير من القيم. تم تطويره بواسطة دبليو دي جونز وتم نشره في عام 1963.
الفكرة الأساسية وراء فرز الدورة هي تقسيم مصفوفة الإدخال إلى دورات حيث تتكون كل دورة من عناصر تنتمي إلى نفس الموضع في مصفوفة الإخراج التي تم فرزها. تقوم الخوارزمية بعد ذلك بإجراء سلسلة من عمليات المبادلة لوضع كل عنصر في موضعه الصحيح خلال دورته حتى تكتمل جميع الدورات ويتم فرز المصفوفة.
فيما يلي شرح خطوة بخطوة لخوارزمية فرز الدورة:
- ابدأ بمصفوفة غير مصنفة من العناصر n.
- تهيئة دورة متغيرة تبدأ من 0.
- لكل عنصر في المصفوفة قارنه بكل عنصر آخر على يمينه. إذا كان هناك أي عناصر أصغر من العنصر الحالي، فقم بزيادة دورة البداية.
- إذا ظلت CycleStart 0 بعد مقارنة العنصر الأول بجميع العناصر الأخرى، فانتقل إلى العنصر التالي وكرر الخطوة 3.
- بمجرد العثور على عنصر أصغر، قم بتبديل العنصر الحالي بالعنصر الأول في دورته. ثم تستمر الدورة حتى يعود العنصر الحالي إلى موضعه الأصلي.
كرر الخطوات من 3 إلى 5 حتى تكتمل جميع الدورات.
تم فرز المصفوفة الآن.
تتمثل إحدى مزايا الفرز الدوري في أنه يحتوي على مساحة ذاكرة منخفضة حيث يقوم بفرز المصفوفة في مكانها ولا يتطلب ذاكرة إضافية للمتغيرات المؤقتة أو المخازن المؤقتة. ومع ذلك، يمكن أن يكون بطيئًا في مواقف معينة، خاصة عندما تحتوي مصفوفة الإدخال على نطاق كبير من القيم. ومع ذلك، يظل الفرز الدوري خوارزمية فرز مفيدة في سياقات معينة، كما هو الحال عند فرز صفائف صغيرة ذات نطاقات قيمة محدودة.
الفرز الدوري هو خوارزمية فرز في المكان خوارزمية الفرز غير المستقرة ونوع المقارنة الأمثل من الناحية النظرية من حيث إجمالي عدد عمليات الكتابة إلى المصفوفة الأصلية.
الكود الرمادي
- إنه الأمثل من حيث عدد الذاكرة المكتوبة. هو - هي يقلل من عدد عمليات الكتابة في الذاكرة للفرز (يتم كتابة كل قيمة صفر مرات إذا كانت في موضعها الصحيح بالفعل أو تتم كتابتها مرة واحدة في موضعها الصحيح.)
- يعتمد ذلك على فكرة أن المصفوفة المراد فرزها يمكن تقسيمها إلى دورات. يمكن تصور الدورات على شكل رسم بياني. لدينا n عقد وحافة موجهة من العقدة i إلى العقدة j إذا كان العنصر الموجود في الفهرس i-th يجب أن يكون موجودًا في الفهرس j-th في المصفوفة التي تم فرزها.
دورة في arr[] = {2 4 5 1 3}
دورة في arr[] = {2 4 5 1 3}- دورة في arr[] = {4 3 2 1}
دورة في arr[] = {4 3 2 1}
نحن نفكر في جميع الدورات واحدًا تلو الآخر. نتناول أولاً الدورة التي تتضمن العنصر الأول. نجد الموضع الصحيح للعنصر الأول ونضعه في موضعه الصحيح مثل j. نأخذ في الاعتبار القيمة القديمة لـ arr[j] ونجد موضعها الصحيح ونستمر في القيام بذلك حتى يتم وضع جميع عناصر الدورة الحالية في الموضع الصحيح، أي أننا لا نعود إلى نقطة بداية الدورة.
البحث الثنائي في جافا
الكود الزائف :
Begin
for
start:= 0 to n - 2 do
key := array[start]
location := start
for i:= start + 1 to n-1 do
if array[i] < key then
location: =location +1
done
if location = start then
ignore lower part go for next iteration
while key = array[location] do
location: = location + 1
done
if location != start then
swap array[location] with key
while location != start do
location start
for i:= start + 1 to n-1 do
if array[i] < key then
location: =location +1
done
while key= array[location]
location := location +1
if key != array[location]
Swap array[location] and key
done
done
End
توضيح :
arr[] = {10 5 2 3}
index = 0 1 2 3
cycle_start = 0
item = 10 = arr[0]
Find position where we put the item
pos = cycle_start
i=pos+1
while(i
if (arr[i] < item)
pos++;
We put 10 at arr[3] and change item to
old value of arr[3].
arr[] = {10 5 2 10 }
item = 3
Again rotate rest cycle that start with index '0'
Find position where we put the item = 3
we swap item with element at arr[1] now
arr[] = {10 3 2 10 }
item = 5
Again rotate rest cycle that start with index '0' and item = 5
we swap item with element at arr[2].
arr[] = {10 3 5 10 }
item = 2
Again rotate rest cycle that start with index '0' and item = 2
arr[] = { 2 3 5 10 }
Above is one iteration for cycle_stat = 0.
Repeat above steps for cycle_start = 1 2 ..n-2
وفيما يلي تنفيذ النهج المذكور أعلاه:
CPP// C++ program to implement cycle sort #include using namespace std; // Function sort the array using Cycle sort void cycleSort(int arr[] int n) { // count number of memory writes int writes = 0; // traverse array elements and put it to on // the right place for (int cycle_start = 0; cycle_start <= n - 2; cycle_start++) { // initialize item as starting point int item = arr[cycle_start]; // Find position where we put the item. We basically // count all smaller elements on right side of item. int pos = cycle_start; for (int i = cycle_start + 1; i < n; i++) if (arr[i] < item) pos++; // If item is already in correct position if (pos == cycle_start) continue; // ignore all duplicate elements while (item == arr[pos]) pos += 1; // put the item to it's right position if (pos != cycle_start) { swap(item arr[pos]); writes++; } // Rotate rest of the cycle while (pos != cycle_start) { pos = cycle_start; // Find position where we put the element for (int i = cycle_start + 1; i < n; i++) if (arr[i] < item) pos += 1; // ignore all duplicate elements while (item == arr[pos]) pos += 1; // put the item to it's right position if (item != arr[pos]) { swap(item arr[pos]); writes++; } } } // Number of memory writes or swaps // cout << writes << endl ; } // Driver program to test above function int main() { int arr[] = { 1 8 3 9 10 10 2 4 }; int n = sizeof(arr) / sizeof(arr[0]); cycleSort(arr n); cout << 'After sort : ' << endl; for (int i = 0; i < n; i++) cout << arr[i] << ' '; return 0; }
Java // Java program to implement cycle sort import java.util.*; import java.lang.*; class GFG { // Function sort the array using Cycle sort public static void cycleSort(int arr[] int n) { // count number of memory writes int writes = 0; // traverse array elements and put it to on // the right place for (int cycle_start = 0; cycle_start <= n - 2; cycle_start++) { // initialize item as starting point int item = arr[cycle_start]; // Find position where we put the item. We basically // count all smaller elements on right side of item. int pos = cycle_start; for (int i = cycle_start + 1; i < n; i++) if (arr[i] < item) pos++; // If item is already in correct position if (pos == cycle_start) continue; // ignore all duplicate elements while (item == arr[pos]) pos += 1; // put the item to it's right position if (pos != cycle_start) { int temp = item; item = arr[pos]; arr[pos] = temp; writes++; } // Rotate rest of the cycle while (pos != cycle_start) { pos = cycle_start; // Find position where we put the element for (int i = cycle_start + 1; i < n; i++) if (arr[i] < item) pos += 1; // ignore all duplicate elements while (item == arr[pos]) pos += 1; // put the item to it's right position if (item != arr[pos]) { int temp = item; item = arr[pos]; arr[pos] = temp; writes++; } } } } // Driver program to test above function public static void main(String[] args) { int arr[] = { 1 8 3 9 10 10 2 4 }; int n = arr.length; cycleSort(arr n); System.out.println('After sort : '); for (int i = 0; i < n; i++) System.out.print(arr[i] + ' '); } } // Code Contributed by Mohit Gupta_OMG <(0_o)>
Python3 # Python program to implement cycle sort def cycleSort(array): writes = 0 # Loop through the array to find cycles to rotate. for cycleStart in range(0 len(array) - 1): item = array[cycleStart] # Find where to put the item. pos = cycleStart for i in range(cycleStart + 1 len(array)): if array[i] < item: pos += 1 # If the item is already there this is not a cycle. if pos == cycleStart: continue # Otherwise put the item there or right after any duplicates. while item == array[pos]: pos += 1 array[pos] item = item array[pos] writes += 1 # Rotate the rest of the cycle. while pos != cycleStart: # Find where to put the item. pos = cycleStart for i in range(cycleStart + 1 len(array)): if array[i] < item: pos += 1 # Put the item there or right after any duplicates. while item == array[pos]: pos += 1 array[pos] item = item array[pos] writes += 1 return writes # driver code arr = [1 8 3 9 10 10 2 4 ] n = len(arr) cycleSort(arr) print('After sort : ') for i in range(0 n) : print(arr[i] end = ' ') # Code Contributed by Mohit Gupta_OMG <(0_o)>
C# // C# program to implement cycle sort using System; class GFG { // Function sort the array using Cycle sort public static void cycleSort(int[] arr int n) { // count number of memory writes int writes = 0; // traverse array elements and // put it to on the right place for (int cycle_start = 0; cycle_start <= n - 2; cycle_start++) { // initialize item as starting point int item = arr[cycle_start]; // Find position where we put the item. // We basically count all smaller elements // on right side of item. int pos = cycle_start; for (int i = cycle_start + 1; i < n; i++) if (arr[i] < item) pos++; // If item is already in correct position if (pos == cycle_start) continue; // ignore all duplicate elements while (item == arr[pos]) pos += 1; // put the item to it's right position if (pos != cycle_start) { int temp = item; item = arr[pos]; arr[pos] = temp; writes++; } // Rotate rest of the cycle while (pos != cycle_start) { pos = cycle_start; // Find position where we put the element for (int i = cycle_start + 1; i < n; i++) if (arr[i] < item) pos += 1; // ignore all duplicate elements while (item == arr[pos]) pos += 1; // put the item to it's right position if (item != arr[pos]) { int temp = item; item = arr[pos]; arr[pos] = temp; writes++; } } } } // Driver program to test above function public static void Main() { int[] arr = { 1 8 3 9 10 10 2 4 }; int n = arr.Length; // Function calling cycleSort(arr n); Console.WriteLine('After sort : '); for (int i = 0; i < n; i++) Console.Write(arr[i] + ' '); } } // This code is contributed by Nitin Mittal
JavaScript <script> // Javascript program to implement cycle sort // Function sort the array using Cycle sort function cycleSort(arr n) { // count number of memory writes let writes = 0; // traverse array elements and put it to on // the right place for (let cycle_start = 0; cycle_start <= n - 2; cycle_start++) { // initialize item as starting point let item = arr[cycle_start]; // Find position where we put the item. We basically // count all smaller elements on right side of item. let pos = cycle_start; for (let i = cycle_start + 1; i < n; i++) if (arr[i] < item) pos++; // If item is already in correct position if (pos == cycle_start) continue; // ignore all duplicate elements while (item == arr[pos]) pos += 1; // put the item to it's right position if (pos != cycle_start) { let temp = item; item = arr[pos]; arr[pos] = temp; writes++; } // Rotate rest of the cycle while (pos != cycle_start) { pos = cycle_start; // Find position where we put the element for (let i = cycle_start + 1; i < n; i++) if (arr[i] < item) pos += 1; // ignore all duplicate elements while (item == arr[pos]) pos += 1; // put the item to it's right position if (item != arr[pos]) { let temp = item; item = arr[pos]; arr[pos] = temp; writes++; } } } } // Driver code let arr = [ 1 8 3 9 10 10 2 4 ]; let n = arr.length; cycleSort(arr n); document.write('After sort : ' + '
'); for (let i = 0; i < n; i++) document.write(arr[i] + ' '); // This code is contributed by susmitakundugoaldanga. </script>
الإخراج
After sort : 1 2 3 4 8 9 10 10
تحليل تعقيد الوقت :
- أسوأ حالة: على2)
- متوسط الحالة: على2)
- أفضل حالة: على2)
المساحة المساعدة: يا(1)
- تعقيد المساحة ثابت لأن هذه الخوارزمية موجودة بحيث لا تستخدم أي ذاكرة إضافية للفرز.
الطريقة الثانية: تنطبق هذه الطريقة فقط عندما تكون قيم أو عناصر المصفوفة في النطاق من 1 إلى N أو من 0 إلى N. في هذه الطريقة لا نحتاج إلى تدوير مصفوفة
يقترب : يجب أن تكون جميع قيم المصفوفة المحددة في النطاق من 1 إلى N أو من 0 إلى N. إذا كان النطاق من 1 إلى N، فسيكون الموضع الصحيح لكل عنصر في المصفوفة هو قيمة الفهرس == -1، أي يعني أن قيمة الفهرس عند رقم 0 ستكون 1 وبالمثل عند قيمة موضع الفهرس الأول ستكون 2 وهكذا حتى القيمة رقم n.
وبالمثل بالنسبة للقيم من 0 إلى N، سيكون موضع الفهرس الصحيح لكل عنصر أو قيمة مصفوفة هو نفس قيمته، أي في الفهرس 0 0 سيكون هناك الموضع الأول 1 سيكون هناك.
عقدة القائمة في جافا
توضيح :
arr[] = {5 3 1 4 2}
index = 0 1 2 3 4
i = 0;
while( i < arr.length)
correctposition = arr[i]-1;
find ith item correct position
for the first time i = 0 arr[0] = 5 correct index of 5 is 4 so arr[i] - 1 = 5-1 = 4
if( arr[i] <= arr.length && arr[i] != arr[correctposition])
arr[i] = 5 and arr[correctposition] = 4
so 5 <= 5 && 5 != 4 if condition true
now swap the 5 with 4
int temp = arr[i];
arr[i] = arr[correctposition];
arr[correctposition] = temp;
now resultant arr at this after 1st swap
arr[] = {2 3 1 4 5} now 5 is shifted at its correct position
now loop will run again check for i = 0 now arr[i] is = 2
after swapping 2 at its correct position
arr[] = {3 2 1 4 5}
now loop will run again check for i = 0 now arr[i] is = 3
after swapping 3 at its correct position
arr[] = {1 2 3 4 5}
now loop will run again check for i = 0 now arr[i] is = 1
this time 1 is at its correct position so else block will execute and i will increment i = 1;
once i exceeds the size of array will get array sorted.
arr[] = {1 2 3 4 5}
else
i++;
loop end;
once while loop end we get sorted array just print it
for( index = 0 ; index < arr.length; index++)
print(arr[index] + ' ')
sorted arr[] = {1 2 3 4 5}
وفيما يلي تنفيذ النهج المذكور أعلاه:
C++#include using namespace std; void cyclicSort(int arr[] int n){ int i = 0; while(i < n) { // as array is of 1 based indexing so the // correct position or index number of each // element is element-1 i.e. 1 will be at 0th // index similarly 2 correct index will 1 so // on... int correct = arr[i] - 1 ; if(arr[i] != arr[correct]){ // if array element should be lesser than // size and array element should not be at // its correct position then only swap with // its correct position or index value swap(arr[i] arr[correct]) ; }else{ // if element is at its correct position // just increment i and check for remaining // array elements i++ ; } } } void printArray(int arr[] int size) { int i; for (i = 0; i < size; i++) cout << arr[i] << ' '; cout << endl; } int main() { int arr[] = { 3 2 4 5 1}; int n = sizeof(arr) / sizeof(arr[0]); cout << 'Before sorting array: n'; printArray(arr n); cyclicSort(arr n); cout << 'Sorted array: n'; printArray(arr n); return 0; }
Java // java program to check implement cycle sort import java.util.*; public class MissingNumber { public static void main(String[] args) { int[] arr = { 3 2 4 5 1 }; int n = arr.length; System.out.println('Before sort :'); System.out.println(Arrays.toString(arr)); CycleSort(arr n); } static void CycleSort(int[] arr int n) { int i = 0; while (i < n) { // as array is of 1 based indexing so the // correct position or index number of each // element is element-1 i.e. 1 will be at 0th // index similarly 2 correct index will 1 so // on... int correctpos = arr[i] - 1; if (arr[i] < n && arr[i] != arr[correctpos]) { // if array element should be lesser than // size and array element should not be at // its correct position then only swap with // its correct position or index value swap(arr i correctpos); } else { // if element is at its correct position // just increment i and check for remaining // array elements i++; } } System.out.println('After sort : '); System.out.print(Arrays.toString(arr)); } static void swap(int[] arr int i int correctpos) { // swap elements with their correct indexes int temp = arr[i]; arr[i] = arr[correctpos]; arr[correctpos] = temp; } } // this code is contributed by devendra solunke
Python # Python program to check implement cycle sort def cyclicSort(arr n): i = 0 while i < n: # as array is of 1 based indexing so the # correct position or index number of each # element is element-1 i.e. 1 will be at 0th # index similarly 2 correct index will 1 so # on... correct = arr[i] - 1 if arr[i] != arr[correct]: # if array element should be lesser than # size and array element should not be at # its correct position then only swap with # its correct position or index value arr[i] arr[correct] = arr[correct] arr[i] else: # if element is at its correct position # just increment i and check for remaining # array elements i += 1 def printArray(arr): print(*arr) arr = [3 2 4 5 1] n = len(arr) print('Before sorting array:') printArray(arr) # Function Call cyclicSort(arr n) print('Sorted array:') printArray(arr) # This Code is Contributed by Prasad Kandekar(prasad264)
C# using System; public class GFG { static void CycleSort(int[] arr int n) { int i = 0; while (i < n) { // as array is of 1 based indexing so the // correct position or index number of each // element is element-1 i.e. 1 will be at 0th // index similarly 2 correct index will 1 so // on... int correctpos = arr[i] - 1; if (arr[i] < n && arr[i] != arr[correctpos]) { // if array element should be lesser than // size and array element should not be at // its correct position then only swap with // its correct position or index value swap(arr i correctpos); } else { // if element is at its correct position // just increment i and check for remaining // array elements i++; } } Console.Write('nAfter sort : '); for (int index = 0; index < n; index++) Console.Write(arr[index] + ' '); } static void swap(int[] arr int i int correctpos) { // swap elements with their correct indexes int temp = arr[i]; arr[i] = arr[correctpos]; arr[correctpos] = temp; } static public void Main() { // Code int[] arr = { 3 2 4 5 1 }; int n = arr.Length; Console.Write('Before sort : '); for (int i = 0; i < n; i++) Console.Write(arr[i] + ' '); CycleSort(arr n); } } // This code is contributed by devendra solunke
JavaScript // JavaScript code for the above code function cyclicSort(arr n) { var i = 0; while (i < n) { // as array is of 1 based indexing so the // correct position or index number of each // element is element-1 i.e. 1 will be at 0th // index similarly 2 correct index will 1 so // on... let correct = arr[i] - 1; if (arr[i] !== arr[correct]) { // if array element should be lesser than // size and array element should not be at // its correct position then only swap with // its correct position or index value [arr[i] arr[correct]] = [arr[correct] arr[i]]; } else { // if element is at its correct position // just increment i and check for remaining // array elements i++; } } } function printArray(arr size) { for (var i = 0; i < size; i++) { console.log(arr[i] + ' '); } console.log('n'); } var arr = [3 2 4 5 1]; var n = arr.length; console.log('Before sorting array: n'); printArray(arr n); cyclicSort(arr n); console.log('Sorted array: n'); printArray(arr n); // This Code is Contributed by Prasad Kandekar(prasad264)
الإخراج
Before sorting array: 3 2 4 5 1 Sorted array: 1 2 3 4 5
تحليل تعقيد الوقت:
- أسوأ حالة : على)
- متوسط الحالة: على)
- أفضل حالة : على)
المساحة المساعدة: يا(1)
الاستفادة من نوع الدورة:
- ليس هناك حاجة لتخزين إضافي.
- خوارزمية الفرز في المكان.
- الحد الأدنى لعدد عمليات الكتابة إلى الذاكرة
- يكون الفرز الدوري مفيدًا عندما يتم تخزين المصفوفة في EEPROM أو FLASH.
عيوب نوع الدورة:
- لا يتم استخدامه في الغالب.
- لديها المزيد من التعقيد الزمني o(n^2)
- خوارزمية الفرز غير المستقرة.
تطبيق الفرز الدوري:
- تعتبر خوارزمية الفرز هذه مناسبة تمامًا للمواقف التي تكون فيها عمليات كتابة الذاكرة أو تبديلها مكلفة.
- مفيد للمشاكل المعقدة.