Sorting algorithm-----counting sort

Table of contents

Foreword:

counting sort

1.Algorithm description

2. Basic idea

 3. Implement logic

4.Example analysis

5. Animation demonstration

Code

1.C/C++ code

2.Python code

Analysis of Algorithms

time complexity 

space complexity

stability

limitation 


Foreword:

        Is there a sorting algorithm whose time complexity is linearly proportional? Of course there is, that is counting sort, so why is the sorting algorithm with such a small time complexity, but its sorting speed is not as good as quick sort (nlogn)? Here we will think that there may be another price to pay. Yes, that is the price to pay for space resources. Let’s take a look together!

counting sort

1.Algorithm description

        Counting sort is a non-comparison-based sorting algorithm proposed by Harold H. Seward in 1954. Its advantage is that when sorting integers within a certain range, its complexity is Ο(n+k) (where k is the range of integers), which is faster than any comparison sorting algorithm. [1] Of course, this is a way of sacrificing space for time, and when O(k)>O(n*log(n)), its efficiency is not as good as comparison-based sorting ( the time complexity   of comparison-based sorting is The theoretical lower limit is O(n*log(n)), such as merge sort and heap sort )

2. Basic idea

Counting sort uses an additional array C, where the i-th element is the number of elements whose value is equal to i in the array A to be sorted.

The core of counting sort is to convert the input data values ​​into keys and store them in the additionally opened array space. As a linear time complexity sort, counting sort requires that the input data must be integers within a certain range.

The length of the array C used for counting depends on the range of the data in the array to be sorted (equal to the difference between the maximum value and the minimum value of the array to be sorted plus 1), and then allocated and collected:

①Distribution  . _ Scan the original array once, use the current value -minValue as the subscript, and increase the counter of the subscript by 1.
②Collect  . _ Scan the counter array and collect the values ​​in order.

 3. Implement logic

① Find the largest and smallest elements in the array to be sorted
② Count the number of occurrences of each element with value i in the array, and store it in the i-th item of array C
③ Accumulate all counts (from the first one in C Starting from the element, each item is added to the previous item)
④ Fill the target array in reverse: Place each element i in the C(i)th item of the new array, and subtract 1 from C(i) for each element placed.

4.Example analysis

Suppose there is an array [2,1,5,1,3,8,4,5,6,10,7]. How to implement sorting through counting sorting?

The first step is to find the maximum max element of this array, which is 10, and then create an array count[max+1], that is, count[11], and initialize all the numbers in count to 0, as shown below:

count          [0,0,0,0,0,0,0,0,0,0,0]

In the second step , start traversing the original array, then count the number of elements in it, and perform a +1 operation in the count array at the corresponding position. For example, if 1 appears twice in the original array, then add 2 to count[0], that is, count[0]=2. Count counts the number of occurrences of the original array elements in sequence. The statistics are as follows:

                 1        2        3        4        5        6        7        8        9        10        

count 2 1 1 1 2 1 1 0 0 1 (these are the number of occurrences counted)

The third step is to fill in and cover the original array in order, and finally get the sorted array.

1        1        2        3        4        5        5        6        7        10

5. Animation demonstration

Code

1.C/C++ code

#include<stdio.h>
#include<string.h>
//获取最大值
int get_max(int* n,int length) {
	int max = n[0];
	for (int i = 1; i < length; i++) {
		if (n[i]>max)
			max = n[i];
	}
	return max;
}

//计数排序
void count_sort(int* n, int max, int length) {
	int index=0;
	int range =max+1;
	int* temp_arr = (int*)malloc(sizeof(int) * range);
	memset(temp_arr, 0, sizeof(int) * range); //初始化全部都为0
	for (int j = 0; j < length; j++) { //统计
		temp_arr[n[j]]++;
	}
	
	for (int k = 0; k < range; k++) {
		while (temp_arr[k]) {
			n[index++]=k;//把统计后的数字覆盖给原数组上
			temp_arr[k]--;
		}
	}
	free(temp_arr);//释放空间
}
int main() {
	int array[11] = { 2,1,5,1,3,8,4,5,6,10,7 };
	printf("排序前:");
	for (int i = 0; i < sizeof(array) / sizeof(int); i++) {
		printf("%d ", array[i]);
	}
	printf("\n排序后:");
	count_sort(array, get_max(array, sizeof(array) / sizeof(int)),sizeof(array) / sizeof(int));
	for (int i = 0; i < sizeof(array) / sizeof(int); i++) {
		printf("%d ", array[i]);
	}
}
//排序前:2 1 5 1 3 8 4 5 6 10 7
//排序后:1 1 2 3 4 5 5 6 7 8 10

2.Python code

import random as r
def count_sort(li,max):
    length=len(li)  #获取长度
    index=0
    new_li=[0 for _ in range(max)] #进入到统计
    for i in li:
        new_li[i-1]+=1
    for j in range(0,len(new_li)): #覆盖原数组
        while new_li[j]:
            li[index]=j+1
            index+=1
            new_li[j]-=1
    return li           

if __name__ == '__main__':
    li=[r.randint(1,10) for _ in range(10)]
    print(li)
    sort_li=count_sort(li,max(li))
    print(sort_li)
    
# [3, 6, 6, 7, 7, 1, 9, 10, 8, 5]
# [1, 3, 5, 6, 6, 7, 7, 8, 9, 10]

Analysis of Algorithms

time complexity 

O(n+k) 

space complexity

O(k)

stability

 Stablize

limitation 

 Note: Counting sorting requires opening up a space of memory to store statistics. If the array to be sorted is very large, the space that needs to be applied for will be very large. This is a waste of space, so Use caution when choosing.

That’s all for today, see you next time!

Share a wallpaper: 

Guess you like

Origin blog.csdn.net/m0_73633088/article/details/132942106