Counting Sort
Ten classic sorting algorithm!
Foreword
pleasebe sureLook at this: sorting algorithms pre-knowledge + code environment ready .
When the contents of the above are ready, then start counting sort it!
Counting sequencing - simple realization
Before learning of the bubble, selection, stack , insert , merge , fast , Hill sorting is based on a comparison sort.
Counting sort, bucket sort, radix sort, are not based on a comparison sort.
- They are typical of a space for time , at some point, the average may be lower than the time complexity O (nlogn)
Counting sequencing in 1954 proposed by Harold H. Seward, suitable for a range ofInteger Sort.
Counting sort of core ideas:
- Each statistics appearing in an integer sequence, and thus derive the integer index of each ordered sequence of
Implementation steps
Ideas:
- To sort the array first identify the maximum value max;
- An array of counts 1 max + open space according to the maximum value max;
- It counts the number of times each integer array of statistics appear;
- According to integer number that appears on the integer sort:
- Traversing the counts array, index is the index element value , counts [index] number of occurrences of element
- The Counts [index] th index sequence into an array, i.e. the sorted sequence
For example, {7, 3, 5, 8, 7, 4, 5} counting sort: max = 8
- counts array is [0, 0, 0, 1, 1, 2, 1, 2, 1]
- Of index = 3, counts [index] = 1, i.e. to a new array 3 placed
at this time for the new array [3] - Of index = 4, counts [index] = 1, i.e., to put in a new array 4
- At this time, the new array is [3, 4]
- For index = 5, counts [index] = 2, i.e., to the new array into two 5
- At this time, the new array is [3, 4, 5, 5]
- For index = 6, counts [index] = 1, i.e., to put in a new array 6
at this time as the new array [3, 4, 5, 5, 6] - For index = 7, counts [index] = 2, i.e., to the new array into two 7
at this time as the new array [3, 4, 5, 5, 6, 7, 7] - For index = 8, counts [index] = 1, i.e., to put in a new array in
this case for the new array [3, 4, 5, 5, 6, 7, 7, 8]
Code implementation and disadvantages
/**
* 计数排序最简单的实例
*/
private void sort0(){
// 找出最大值
int max = array[0];
for(int i = 1; i < array.length; i++){
if(array[i] > max){
max = array[i];
}
}
// 根据最大值来开辟内存空间
int[] counts = new int[max + 1];
// 统计每个整数出现的次数
for(int i = 0; i < array.length; i++){
counts[array[i]]++;
}
// 根据整数出现的次数,对整数进行排序
int index = 0;
for(int i = 0; i < counts.length; i++){
while(counts[i]-- > 0){
array[index++] = i;
}
}
}
This version of the following problems to achieve
- Can not negative integers sort
- Extremely wasteful of memory space
- It is an unstable sort
- …
Counting sequencing - Improvement
Improvement idea is to find a minimum .
Improvement - illustration
Each element tired by the location of its elements all of the foregoing elements is obtained in the ordered sequence.
For example, {7, 3, 5, 8, 6, 7, 4, 5} improvement over the counting sequencing: min = 3, max = 8
newArray for the opening of the new array , newArray = [0, 0, 0, 0 , 0, 0, 0, 0], is used to store the sort results .
-
counts = [1, 2, 4 , 5, 7, 8];
element 5 in the ordered sequence of indexing of: Counts [5 -. 3] - = Counts. 1 [2] -. 1. 3 =
newArray [. 3] = 5 ; case = newArray [0, 0, 0,. 5, 0, 0, 0, 0]
Counts [2] -;
-
counts = [1, 2, 3 , 5, 7, 8];
element 4 in the ordered sequence of indexing of: Counts [4 -. 3] -. 1 = Counts [. 1] - =. 1. 1
newArray [. 1] = 4 ; case = newArray [0,. 4, 0,. 5, 0, 0, 0, 0]
Counts [. 1] -; -
counts = [1, 1, 3 , 5, 7, 8];
element 7 in the ordered sequence of indexing of: Counts [7 -. 3] -. 1 = Counts [. 4] -. 1. 6 =
newArray [. 6] = 7 ; case = newArray [0,. 4, 0,. 5, 0, 0,. 7, 0]
Counts [. 4] -;
-
counts = [1, 1, 3 , 5, 6, 8];
element 6 in the ordered sequence of indexing of: Counts [6 -. 3] -. 1 = Counts [. 3] -. 1. 4 =
newArray [. 4] = 6 ; case = newArray [0,. 4, 0,. 5,. 6, 0,. 7, 0]
Counts [. 3] -; -
counts = [1, 1, 3 , 4, 6, 8];
element 8 of the index in the ordered sequence of: Counts [8 -. 3] -. 1 = Counts [. 5] -. 1. 7 =
newArray [. 7] = 8 ; case = newArray [0,. 4, 0,. 5,. 6, 0,. 7,. 8]
Counts [. 5] -;
-
counts = [1, 1, 3 , 4, 6, 7];
element 5 in the ordered sequence of indexing of: Counts [5 -. 3] = -1 Counts [2] - = 2. 1
newArray [2] = 5 ; case = newArray [0,. 4,. 5,. 5,. 6, 0,. 7,. 8]
Counts [2] -; -
counts = [1, 1, 2 , 4, 6, 7];
element 3 in the ordered sequence of indexing of: Counts [3 - 3] -. 1 = Counts [0] - = 0. 1
newArray [0] = 3 ; case = newArray [. 3,. 4,. 5,. 5,. 6, 0,. 7,. 8]
Counts [0] -;
-
counts = [0, 1, 2 , 4, 6, 7];
element 7 in the ordered sequence of indexing of: Counts [7 -. 3] -. 1 = Counts [. 4] -. 1. 5 =
newArray [. 5] =. 8 ; case = newArray [. 3,. 4,. 5,. 5,. 6,. 7,. 7,. 8]
Counts [. 5] -;
Improvement - realization
/**
* 计数排序
*/
public class CountingSort extends Sort<Integer>{
@Override
protected void sort() {
// 找出最值
int max = array[0];
int min = array[0];
for(int i = 0; i < array.length; i++){
if(array[i] < min){
min = array[i];
}
if(array[i] > max){
max = array[i];
}
}
// 开辟内存空间,存储次数
int[] counts = new int[max - min + 1];
// 统计每个整数出现的次数
for(int i = 0; i < array.length; i++){
counts[array[i] - min]++;
}
// 累加次数
for(int i = 1; i < counts.length; i++){
counts[i] += counts[i - 1];
}
// 从后往前遍历元素,将它放到有序数组中的合适位置
int[] newArray = new int[array.length];
for(int i = array.length - 1; i >= 0; i--){
newArray[--counts[array[i] - min]] = array[i];
}
// 将有序数组赋值到array
for (int i = 0; i < newArray.length; i++) {
array[i] = newArray[i];
}
}
}
Complexity and stability
- Preferably, the worst, the average time complexity: O (n + k)
- Space complexity: O (n + k)
- k is an integer in the range of
- Counting sequencing belonging stable sort
Counting sequencing - sort of custom objects
If the custom object to provide sort of integer type, a count may still sort
private static class Person {
int age;
String name;
Person(int age, String name) {
this.age = age;
this.name = name;
}
@Override
public String toString() {
return "Person [age=" + age
+ ", name=" + name + "]";
}
}
public static void main(String[] args) {
Person[] persons = new Person[] {
new Person(20, "A"),
new Person(-13, "B"),
new Person(17, "C"),
new Person(12, "D"),
new Person(-13, "E"),
new Person(20, "F")
};
// 找出最值
int max = persons[0].age;
int min = persons[0].age;
for (int i = 1; i < persons.length; i++) {
if (persons[i].age > max) {
max = persons[i].age;
}
if (persons[i].age < min) {
min = persons[i].age;
}
}
// 开辟内存空间,存储次数
int[] counts = new int[max - min + 1];
// 统计每个整数出现的次数
for (int i = 0; i < persons.length; i++) {
counts[persons[i].age - min]++;
}
// 累加次数
for (int i = 1; i < counts.length; i++) {
counts[i] += counts[i - 1];
}
// 从后往前遍历元素,将它放到有序数组中的合适位置
Person[] newArray = new Person[persons.length];
for (int i = persons.length - 1; i >= 0; i--) {
newArray[--counts[persons[i].age - min]] = persons[i];
}
// 将有序数组赋值到array
for (int i = 0; i < newArray.length; i++) {
persons[i] = newArray[i];
}
for (int i = 0; i < persons.length; i++) {
System.out.println(persons[i]);
}
}
Sort results:
Person [age=-13, name=B]
Person [age=-13, name=E]
Person [age=12, name=D]
Person [age=17, name=C]
Person [age=20, name=A]
Person [age=20, name=F]