📜  循环排序

📅  最后修改于: 2021-04-24 18:10:50             🧑  作者: Mango

循环排序是一种就地排序算法,一种不稳定的排序算法,一种比较排序,在理论上,对原始数组的写入总数在比较上是最佳的。

  • 就内存写入次数而言,这是最佳的。它最大程度地减少了要排序的内存写操作的数量(每个值要么被写入零次(如果它已经处于其正确位置,要么被写入一次至其正确位置)。)
  • 基于这样的思想,可以将要排序的数组划分为多个循环。周期可以显示为图表。如果在排序数组中第i个索引处的元素必须出现在第j个索引处,则我们有n个节点和从节点i指向节点j的边。
    以arr [] = {2,4,5,1,3}循环

循环排序

  • 以arr [] = {4,3,2,1}循环

cyclc-sort2

我们一个接一个地考虑所有周期。我们首先考虑包含第一个元素的循环。我们找到第一个元素的正确位置,将其放置在正确的位置,例如j。我们考虑arr [j]的旧值并找到其正确位置,直到当前循环的所有元素都放置在正确位置之前,我们一直这样做,即,我们不回到循环起点。

解释 :

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
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.Write("After sort : ");
        for (int i = 0; i < n; i++)
            Console.Write(arr[i] + " ");
    }
}
 
// This code is contributed by Nitin Mittal


Javascript


输出:

After sort : 
1 2 3 4 8 9 10 10 

时间复杂度:O(n 2 )
最坏的情况:O(n 2 )
平均情况:O(n 2 )
最佳情况:O(n 2 )
这种排序算法最适合于内存写或交换操作非常昂贵的情况。