基数排序
基数排序是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。有时候有些属性是有优先级顺序的,先按低优先级排序,再按高优先级排序。最后的次序就是高优先级高的在前,高优先级相同的低优先级高的在前。
缺点:必须是数字且整数,轮次按最大数的位数决定。
import p3.链式结构.LinkedList;
public class RadixSort extends Sort{
public RadixSort(int[] arr) {
super(arr);
}
@Override
public void sort() {
//1.找 分类-收集 的轮数(最大值的长度)
int radix = getRadix();
//2.创建桶 list所有桶的集合 每一个桶是LinkedList当成队列来用
LinkedList<Integer>[] list = new LinkedList[10];
for (int i = 0; i < list.length; i++) {
list[i] = new LinkedList<>();
}
//3.开始 分类-收集
for (int r = 1; r <= radix; r++) {
//分类过程
for (int i = 0; i < arr.length; i++) {
list[getIndex(arr[i], r)].offer(arr[i]);//找到对应的桶并进队
}
int index = 0; //遍历arr原数组
//收集的过程
for (int i = 0; i < list.length; i++) {
while (!list[i].isEmpty()) {
arr[index++] = list[i].poll();
}
}
}
}
private int getIndex(int num, int r) {
//如何获取当前数字位次上的值
int ret = 0;
for (int i = 1; i <= r; i++) {
ret = num % 10;
num /= 10;
}
return ret;
}
private int getRadix() {
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
return (max + "").length();
}
}
桶排序
桶排序是计数排序的升级版。它利用了函数的映射关系,高效与否的关键就在于这个映射函数的确定。桶排序 (Bucket sort)的工作的原理:假设输入数据服从均匀分布,将数据分到有限数量的桶里,每个桶再分别排序(有可能再使用别的排序算法或是以递归方式继续使用桶排序进行排)。
缺点如果最大最小差值过大,而数据数量不够多,会分出很多个桶。
import java.util.ArrayList;
import java.util.Comparator;
//桶排序 List[i]代表i个桶 将list与arr分辨开
public class BucketSort extends Sort{
public BucketSort(int[] arr) {
super(arr);
}
@Override
public void sort() {
//1.找到最大值和最小值
int max = arr[0];
int min = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
if (arr[i] < min) {
min = arr[i];
}
}
//2.确定桶的个数并创建桶
int bucketNum = (max - min) / arr.length + 1;
ArrayList<Integer> list[] = new ArrayList[bucketNum];
for (int i = 0; i < list.length; i++) {
list[i] = new ArrayList<>();
}
//3.遍历源数据 将数据进行分类处理
for (int i = 0; i < arr.length; i++) {
//将数据存进桶
list[(arr[i] - min) / arr.length].add(arr[i]);
}
//4.对每一个桶进行排序
for (int i = 0; i < list.length; i++) {
list[i].sort(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1 - o2;//升序
}
});
// 测试 System.out.println("第" + (i+1) + "个桶:" + list[i].toString());
}
//5.将所有桶中的数据依次返回到原数组中即可
int index = 0; //原数组的角标
for (int i = 0; i < list.length; i++) {
for (int j = 0; j < list[i].size(); j++) {
arr[index++] = list[i].get(j);//挨个遍历每个桶
}
}
// 测试 System.out.println(Arrays.toString(arr));
}
}