笔者之前的博客提到过七种经典排序算法,他们分别是:
- 时间复杂度为:O(n²)的算法:冒泡排序,选择排序,插入排序
- 时间复杂度为:O(n*㏒n)的算法:归并排序,快速排序,堆排序,希尔排序
那么本篇的内容将要介绍两种时间复杂度为O(n)的排序算法,分别是:计数排序和基数排序
这两种算法不是基于比较的的排序算法,主要思想原形是基于桶排序,所谓的桶排序不是一种具体的实现而是一种思想。
一、计数排序
原理及思路:
例如现在需要将员工的身高进行从低到高排序,我们已知成年人的身高在100cm到300cm之间,这个时候我们可以设置100号到300号这200个桶,然后将员工根据身高的大小放入每一个桶中,然后依次到处100号到300号中的员工,这样最后的结果就有序了。
代码举例:
import java.util.*;
public class CountingSort {
public int[] countingSort(int[] A, int n) {
// write code here
//如果数组为空,则无需排序
if(A == null || n<1){
return A;
}
//否则
//首先我们需要设置一些桶,这里桶的数量我用 数组中的最大数减最小数决定
//所以首先我们要取到数组中的最大数和最小数
//声明两个变量表示
int max = A[0];
int min = A[0];
//遍历数组,找出最大最小值
for(int i=0;i<n;i++){
if(max < A[i]){
max = A[i];
}
if(min > A[i]){
min = A[i];
}
}
//根据最大最小值建立一个数组表示桶
int temp[] = new int[max-min+1];
//遍历数组将数组中的值放入桶中,同时桶数组记录数量,这时用桶数组的下标表示目标数组和最小值的差别,桶数组中存放数量
for(int i=0;i<n;i++){
temp[A[i]-min] += 1;
}
//存放完成后将桶中数字依次倒出,
int index = 0; //表示下标
for(int i=0;i<max-min+1;i++){
while(temp[i] > 0){
//从桶中取出一个树
A[index++] = i + min;
//桶中数量减一
temp[i]--;
}
}
return A;
}
}
二、基数排序
原理及思路:
还是例如将公司员工的身高进行从低到高排序,我们已知身高用十进制表示,那么我们可以创建0号到9号一共十个桶,第一步现将所有元素的各位与桶编号对比,并将其放入对应的桶中,然后从0号到9号依次倒出;第二步,根据倒出来以后的顺序依次将十位数和桶编号比较,然后放入对应的桶中,再依次将桶中的元素倒出来;第三步,将百位数做和前面两次一样的操作,最后依次倒出桶中的元素,那么最后的数组就是排序后的结果。
代码举例:
import java.util.*;
public class RadixSort {
public int[] radixSort(int[] A, int n) {
// write code here
if(A == null || n<1){
return A;
}
//首先我们需要创建十个桶,每个桶中存放最多n个数
int[][] temp = new int[10][n];
//记录存放的数据数
int[] count = new int[10];
//定义变量表示身高区间
int i = 1;
while(i<1000){
//遍历数组
for(int j=0;j<n;j++){
//求计算的位数,这里i是会变的
int pos = A[j]/i%10;
//将元素放入对应的桶
temp[pos][count[pos]++] = A[j];
}
//设置参数表示下标
int index = 0;
//接下来要将桶中的元素倒出来,依次根据一维坐标和二维坐标取出
for(int k=0;k<10;k++){
for(int m=0;m<count[k];m++){
A[index++] = temp[k][m];
}
//全部取出后将计数数组置为0
count[k] = 0;
}
//提高位数
i*=10;
}
return A;
}
}
经典排序总结
经典排序算法空间复杂度
1、O(1)
时间复杂度为O(n²):冒泡排序、插入排序、选择排序
时间复杂度为O(n*㏒n):堆排序,希尔排序
2、O(㏒n)~O(n)
快速排序,这个区间具体的值取决于被排列的数组的分布情况的好坏。
3、O(n)
归并排序
4、O(m)
计数排序,基数排序。这里的m指的是桶的大小
经典排序算法的稳定性
1、不稳定的算法
希尔排序,堆排序,选择排序,快速排序
2、稳定的算法
冒泡排序,插入排序,归并排序,计数排序,基数排序,桶排序