Cyklické řazení
Cyklické řazení je na místě nestabilní třídicí algoritmus, který je zvláště užitečný při řazení polí obsahujících prvky s malým rozsahem hodnot. Byl vyvinut W. D. Jonesem a publikován v roce 1963.
Základní myšlenkou řazení cyklů je rozdělení vstupního pole do cyklů, kde každý cyklus sestává z prvků, které patří na stejnou pozici v seřazeném výstupním poli. Algoritmus poté provede řadu výměn, aby umístil každý prvek na správnou pozici v rámci svého cyklu, dokud nejsou všechny cykly dokončeny a pole není setříděno.
Zde je podrobné vysvětlení algoritmu řazení cyklu:
- Začněte s netříděným polem n prvků.
- Inicializujte proměnnou cycleStart na 0.
- Pro každý prvek v poli jej porovnejte s každým dalším prvkem napravo. Pokud existují nějaké prvky, které jsou menší než aktuální přírůstek prvku cycleStart.
- Pokud je cycleStart po porovnání prvního prvku se všemi ostatními prvky stále 0, přejděte na další prvek a opakujte krok 3.
- Jakmile je nalezen menší prvek, vyměňte aktuální prvek za první prvek v jeho cyklu. Cyklus pak pokračuje, dokud se aktuální prvek nevrátí do své původní polohy.
Opakujte kroky 3-5, dokud nebudou dokončeny všechny cykly.
Pole je nyní seřazeno.
Jednou z výhod cyklického řazení je, že má nízkou paměťovou náročnost, protože třídí pole na místě a nevyžaduje další paměť pro dočasné proměnné nebo vyrovnávací paměti. V určitých situacích však může být pomalý, zejména když má vstupní pole velký rozsah hodnot. Cyklické třídění však zůstává užitečným třídicím algoritmem v určitých kontextech, například při třídění malých polí s omezenými rozsahy hodnot.
Cyklické řazení je algoritmus řazení na místě nestabilní algoritmus řazení a srovnávací řazení, které je teoreticky optimální z hlediska celkového počtu zápisů do původního pole.
- Je optimální z hlediska počtu zápisů do paměti. To minimalizuje počet zápisů do paměti seřadit (Každá hodnota je buď zapsána nulakrát, pokud je již na správné pozici, nebo jednou zapsána na správnou pozici.)
- Je založen na myšlence, že pole, které se má třídit, lze rozdělit do cyklů. Cykly lze zobrazit jako graf. Máme n uzlů a hranu směrovanou z uzlu i do uzlu j, pokud prvek na i-tém indexu musí být přítomen na j-tém indexu v seřazeném poli.
Cyklus v arr[] = {2 4 5 1 3}
Cyklus v arr[] = {2 4 5 1 3} - Cyklus v arr[] = {4 3 2 1}
Cyklus v arr[] = {4 3 2 1}
Jeden po druhém zvažujeme všechny cykly. Nejprve zvážíme cyklus, který obsahuje první prvek. Najdeme správnou polohu prvního prvku a umístíme ho na správnou pozici, řekněme j. Uvážíme starou hodnotu arr[j] a najdeme její správnou polohu. Takto pokračujeme, dokud nejsou všechny prvky aktuálního cyklu umístěny na správnou pozici, tj. nevrátíme se zpět do počátečního bodu cyklu.
Pseudokód:
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
EndVysvětlení:
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-2Níže je uvedena implementace výše uvedeného přístupu:
CPPJava// C++ program to implement cycle sort #includeusing 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 ; } Python3// 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)>C## 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)>JavaScript// 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< 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>
VýstupAfter sort : 1 2 3 4 8 9 10 10Analýza časové složitosti :
- Nejhorší případ: Na 2 )
- Průměrný případ: Na 2 )
- Nejlepší případ: Na 2 )
Pomocný prostor: O(1)
- Prostorová složitost je konstantní, protože tento algoritmus je na místě, takže ke třídění nepoužívá žádnou paměť navíc.
Metoda 2: Tato metoda je použitelná pouze v případě, že dané hodnoty nebo prvky pole jsou v rozsahu 1 až N nebo 0 až N. Při této metodě nepotřebujeme pole otáčet
přístup: Všechny uvedené hodnoty pole by měly být v rozsahu 1 až N nebo 0 až N. Pokud je rozsah 1 až N , pak správná pozice každého prvku pole bude index == hodnota-1, tj. průměr na 0. hodnotě indexu bude 1, podobně na 1. pozici indexu bude hodnota 2 a tak dále až do n-té hodnoty.
podobně pro hodnoty 0 až N bude správná poloha indexu každého prvku pole nebo hodnota stejná jako jeho hodnota, tj. na 0. indexu tam bude 0, bude tam 1. pozice.
Vysvětlení:
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}Níže je uvedena implementace výše uvedeného přístupu:
C++Java#includeusing 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 ; } Python// 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 solunkeC## 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)JavaScriptusing 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 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)
VýstupBefore sorting array: 3 2 4 5 1 Sorted array: 1 2 3 4 5Analýza časové složitosti:
- Nejhorší případ: Na)
- Průměrný případ: Na)
- Nejlepší případ: Na)
Pomocný prostor: O(1)
Výhoda cyklického řazení:
- Není potřeba žádné další úložiště.
- Algoritmus řazení na místě.
- Minimální počet zápisů do paměti
- Cyklické řazení je užitečné, když je pole uloženo v EEPROM nebo FLASH.
Nevýhoda cyklického řazení:
- Většinou se nepoužívá.
- Má větší časovou složitost o (n^2)
- Nestabilní algoritmus řazení.
Aplikace cyklického řazení:
Vytvořit kvíz
- Tento třídicí algoritmus se nejlépe hodí pro situace, kde jsou operace zápisu do paměti nebo swapování nákladné.
- Užitečné pro složité problémy.