Counting sorting (Introduction to algorithms p98)

Source: Internet
Author: User

 

 

Counting sorting is a sort method with algorithm complexity O (N). It is suitable for sorting small sets. For example, if 1 million students take the college entrance examination, we want to sort the scores of these 1 million students (assuming the scores are 0 to 100. How can we design the most efficient sorting algorithm. This article not only describes the traditional method of counting and sorting algorithms, but also discusses algorithm optimization step by step until the time complexity and space complexity are optimal.

First, let's look at the definition of counting sorting.

Counting sort(Sometimes referred to
Ultra sortOrMath sort[1]) is
Sorting Algorithm Which (like
Bucket sort) takes advantage of knowing
Range of the numbers in
Array to be sorted (Array
A). It uses this range to create an arrayCOf this length. Each index
IIn ArrayCIs then used to count how many elements inAHave the value
I; Then counts stored inCCan then be used to put the elements in
AInto their right position in the resulting sorted array. The algorithm was created
Harold H. Seward in 1954.

Counting sorting is a Sort Algorithm Similar to bucket sorting. Its advantage is to sort arrays with a known number range. It creates an array C with the length of this data range. In C, each element record needs to sort the number of corresponding records in the array. This algorithm was proposed by Harold H. Seward in 1954.

The following example shows the algorithm.

Assume that the array to be sorted is a = {, 3, 1, 1}

Here, the maximum value is 3 and the minimum value is 0. Then we create an array C with a length of 4.

Then, scan array a to obtain the total number of elements in array A and keep them in the corresponding unit of array C.

For example, if 0 appears twice, C [0] = 2; if 1 appears four times, C [1] = 4

 

Because C is based on the element of A, in this case, the elements of a naturally become ordered in C. Here we can know that the order is 0, 1, 3 (the Count of 2 is 0)

Then we expand the records in C to the output array B Based on the count of each element, and the sorting is complete.

That is, B [0] to B [1] is 0 B [2] to B [5] is 1.

This sort algorithm relies on an auxiliary array. It is not based on comparison, and the algorithm complexity is O (n). However, because an auxiliary array C is required, the space complexity is greater, due to limited computer memory, this algorithm is not suitable for sorting large numbers.

Note: The optimal average time complexity of a comparison-based sorting algorithm is O (nlogn)

 

Counting sort
Depends on a key assumption: numbers to be sorted are integers in {0, 1,..., k }.
Input: A [1 .. n], where a [J] ε {0, 1 ,..., k} for j = 1, 2 ,..., n. array A and
Values N and K are given as parameters.
Output: B [1. N], sorted. B is assumed to be already allocated and is given as
Parameter.
Auxiliary storage: C [0 .. k]
8-4 lecture notes for Chapter 8: Sorting in linear time
Counting-sort (A, B, n, k)
For I limit 0 to K
Do C [I] defaults 0
For J between 1 to n
Do C [A [J] ← C [A [J] + 1
For I want 1 to K
Do C [I] Objective C [I] + C [I −1]
For J then n downto 1
Do B [C [A [J] Then a [J]
C [A [J] Objective C [A [J] −1
Do an example for a = 21, 51, 31, 01, 22, 32, 02, 33
Counting sort is stable (keys with same value appear in same order in output
They did in input) because of how the last loop works.

The above section is based on the technical sorting section of the MIT computer algorithm textbook. I will not translate it. This is a typical solution of this algorithm. I use it as solution 1.

The actual number of scans for this algorithm is n + K (excluding the number of writes)

Solution 1

 

publicstaticvoid Sort(int[] A, outint[] B, int k)
        {
            Debug.Assert(k > 0);
            Debug.Assert(A != null);
 
int[] C = newint[k + 1];
            B = newint[A.Length];
 
for (int j = 0; j < A.Length; j++)
            {
                C[A[j]]++;
            }
 
for (int i = 1; i <= k; i++)
            {
                C[i] += C[i-1];
            }
 
for (int j = A.Length - 1; j >= 0; j--)
            {
                B[C[A[j]]-1] = A[j];
                C[A[j]]--;
            }
 
        }

The above code is the solution of solution 1 and the classic solution of the counting sorting algorithm. This is also the solution in the textbooks of Massachusetts. However, this solution is not optimal, because the space complexity should be optimized. We can sort a directly instead of the output array B. Before proceeding to solution 2, I suggest you think about it yourself to see if you can omit array B.

 

Solution 2

We optimized the above Code.

publicstaticvoid Sort(int[] A, int k)        {            Debug.Assert(k > 0);            Debug.Assert(A != null);            int[] C = newint[k + 1];            for (int j = 0; j < A.Length; j++)            {                C[A[j]]++;            }            int z = 0;            for (int i = 0; i <= k; i++)            {                while (C[i]-- > 0)                {                    A[z++] = i;                }            }        }

Because the subscript I of the C array is the value of a, we do not need to keep the original number of a. This code reduces an array B and is much simpler than the original code.

 

Comparison with the speed of quick sorting

Take the example of the first college entrance examination score in this article as an example.

int[] A = newint[1000000];
int[] B = newint[1000000];
 
            Random rand = new Random();
 
for (int i = 0; i < A.Length; i++)
            {
                A[i] = rand.Next(0, 100);
            }
 
            A.CopyTo(B, 0);
 
            Stopwatch sw = new Stopwatch();
            sw.Start();
            Array.Sort(B);
            sw.Stop();
            Console.WriteLine(sw.ElapsedMilliseconds);
 
            sw.Reset();
            sw.Start();
 
            CountingSort.Sort(A, 100);
            sw.Stop();
            Console.WriteLine(sw.ElapsedMilliseconds);

Output result

134 // quick sorting
18 // count sorting

It can be seen that counting sorting is about 6 times faster than fast sorting.

From http://www.cnblogs.com/eaglet/archive/2010/09/16/1828016.html

Certificate -----------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

// Implementation 1 # include <stdio. h> # define lengtha 6 # define limit 10 void counting_sort (int * a, int N, int * B, int K); int main () {int I, A [lengtha] = {0, 3, 2, 5, 8, 4}, B [lengtha] = {0}; counting_sort (A, lengtha, B, limit ); for (I = 1; I <lengtha; I ++) printf ("% d,", B [I]); Return 0;} void counting_sort (int *, int N, int * B, int K) {int I, j, * C; C = (int *) malloc (4 * k + 4); for (I = 0; I <K; I ++) // For I <-0 to k c [I] = 0; // do C [I] <-0 for (j = 1; j <n; j ++) // for j <-1 to length [a], so that n = lengtha C [A [J] ++; // do C [A [J] <-C [A [J] + 1/C [I] contains the number of elements equal to I for (I = 1; I <K; I ++) // For I <-1 to k c [I] + = C [I-1]; // do C [I] <-+ C [I-1] // C [I] contains the number of elements less than or equal to I for (j = n-1; j> = 1; J --) // for j <-length [a] downto 1 {B [C [A [J] = A [J]; // do B [C [A [J] <-A [J] C [A [J] --; // C [A [J] <-C [A [J]-1} Free (c );}

// Implementation 2 # include <stdio. h> int A [100], B [100]; void counting_sort (int A [], int B [], int K, int L) {int I, J; int C [100] = {0}; For (j = 0; j <L; j ++) C [A [J] ++; for (I = 1; I <= K; I ++) C [I] = C [I] + C [I-1]; for (j = L-1; j> = 0; j --) {B [C [A [J]-1] = A [J]; C [A [J] --;} for (I = 0; I <L; I ++) printf ("% d", B [I]); printf ("\ n");}/* improved version, the void counting_sort (int A [], int K, int L) {Int J; int C [100] = {0}; For (j = 0; j <L; j ++) C [A [J] ++; int Z = 0; For (j = 0; j <= K; j ++) while (C [I] --> 0) A [Z ++] = I; because the subscript I of the C array is the value of a, we do not need to keep the original number of a. This code reduces an array B and is much simpler than the original code. } */INT main () {int I = 0;/* While (scanf ("% d", & A [I])! = EOF) {I ++;} */for (I = 0; I <8; I ++) scanf ("% d", & A [I]); counting_sort (a, B, 6, I );}

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.