logo

순환 정렬

GfG Practice에서 사용해 보세요. 순환 정렬' title=

순환 정렬은 작은 범위의 값을 가진 요소가 포함된 배열을 정렬할 때 특히 유용한 내부 불안정 정렬 알고리즘입니다. W. D. Jones가 개발하여 1963년에 출판했습니다.

사이클 정렬의 기본 아이디어는 입력 배열을 사이클로 나누는 것입니다. 각 사이클은 정렬된 출력 배열의 동일한 위치에 속하는 요소로 구성됩니다. 그런 다음 알고리즘은 일련의 교체를 수행하여 모든 주기가 완료되고 배열이 정렬될 때까지 주기 내에서 각 요소를 올바른 위치에 배치합니다.

다음은 순환 정렬 알고리즘에 대한 단계별 설명입니다.

  1. 정렬되지 않은 n개 요소의 배열로 시작합니다.
  2. 변수 CycleStart를 0으로 초기화합니다.
  3. 배열의 각 요소에 대해 오른쪽에 있는 다른 모든 요소와 비교합니다. 현재 요소보다 작은 요소가 있는 경우에는 CycleStart를 증가시킵니다.
  4. 첫 번째 요소를 다른 모든 요소와 비교한 후에도 CycleStart가 여전히 0이면 다음 요소로 이동하고 3단계를 반복합니다.
  5. 더 작은 요소가 발견되면 현재 요소를 해당 주기의 첫 번째 요소로 바꿉니다. 그런 다음 현재 요소가 원래 위치로 돌아올 때까지 사이클이 계속됩니다.

모든 주기가 완료될 때까지 3~5단계를 반복합니다.

이제 배열이 정렬되었습니다.

순환 정렬의 장점 중 하나는 배열을 제자리에서 정렬하고 임시 변수나 버퍼를 위한 추가 메모리가 필요하지 않기 때문에 메모리 공간이 적다는 것입니다. 그러나 특히 입력 배열의 값 범위가 큰 특정 상황에서는 속도가 느려질 수 있습니다. 그럼에도 불구하고 순환 정렬은 제한된 값 범위로 작은 배열을 정렬할 때와 같은 특정 상황에서 유용한 정렬 알고리즘으로 남아 있습니다.

순환 정렬은 내부 정렬 알고리즘입니다. 불안정한 정렬 알고리즘 원본 배열에 대한 총 쓰기 수 측면에서 이론적으로 최적인 비교 정렬입니다. 
 

mysql 워크벤치를 사용하는 방법
  • 메모리 쓰기 횟수 측면에서 최적입니다. 그것 메모리 쓰기 횟수를 최소화합니다. 정렬(각 값은 이미 올바른 위치에 있는 경우 0번 기록되거나 올바른 위치에 한 번 기록됩니다.)
  • 정렬할 배열을 여러 사이클로 나눌 수 있다는 아이디어에 기초합니다. 주기를 그래프로 시각화할 수 있습니다. i번째 인덱스의 요소가 정렬된 배열의 j번째 인덱스에 있어야 하는 경우 n개의 노드와 노드 i에서 노드 j로 향하는 간선이 있습니다. 
    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)

  • 공간 복잡도는 이 알고리즘이 적용되어 정렬에 추가 메모리를 사용하지 않기 때문에 일정합니다.

방법 2: 이 방법은 주어진 배열 값이나 요소가 1~N 또는 0~N 범위에 있는 경우에만 적용 가능합니다. 이 방법에서는 배열을 회전할 필요가 없습니다.

접근하다 : 주어진 모든 배열 값은 1~N 또는 0~N 범위에 있어야 합니다. 범위가 1~N인 경우 모든 배열 요소의 올바른 위치는 index == value-1이 됩니다. 즉, 0번째 인덱스 값은 1이 되고, 마찬가지로 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)

사이클 정렬의 장점:

  1. 추가 저장 공간이 필요하지 않습니다.
  2.  내부 정렬 알고리즘.
  3.  메모리에 대한 최소 쓰기 횟수
  4.  사이클 정렬은 어레이가 EEPROM 또는 FLASH에 저장되어 있을 때 유용합니다. 

순환 정렬의 단점:

  1.  대부분 사용되지 않습니다.
  2.  시간 복잡도가 더 높습니다. o(n^2)
  3.  불안정한 정렬 알고리즘.

순환 정렬 적용:

  • 이 정렬 알고리즘은 메모리 쓰기 또는 스왑 작업에 비용이 많이 드는 상황에 가장 적합합니다.
  • 복잡한 문제에 유용합니다. 
     
퀴즈 만들기