排序算法(三):归并、基数排序的JAVA实现
常见的8大排序算法分类如下:
归并、基数都需要开辟新的存储空间,以内存换时间,加快排序速度。
一、归并
分治思想。
治阶段:最后一步为例
代码实现:详情思路见代码注释
package test.sort;
import java.util.Arrays;
/**
* @author shkstart
* @create 2021-01-10 18:26
*/
public class MergetSort {
public static void main(String[] args) {
int[] arr = new int[]{8, 4, 5, 7, 1, 3, 6, 2};
int[] temp = new int[arr.length];
mergeSort(arr,0,arr.length-1,temp);
System.out.println(Arrays.toString(arr));
}
//分+合的方法,使用了递归回溯
public static void mergeSort(int[] arr, int left, int right, int[] temp) {
if (left < right) {
int mid = (left + right) / 2;
mergeSort(arr, left, mid, temp);//向左递归
mergeSort(arr, mid + 1, right, temp);//向右递归
merge(arr, left, mid, right, temp);
}
}
/**
* 合并的方法
*
* @param arr
* @param left
* @param mid
* @param right
* @param temp
*/
public static void merge(int[] arr, int left, int mid, int right, int[] temp) {
System.out.println("****");//通过输出语句可看到该方法调用了几次
int i = left;
int j = mid + 1;
int t = 0;
//填充到temp数组中,直到某一边的序列处理完毕,
while (i <= mid && j <= right) {
if (arr[i] <= arr[j]) {
temp[t] = arr[i];
t++;
i++;
} else {
temp[t] = arr[j];
t++;
j++;
}
}
//将剩余的一个序列所有元素填充到temp数组中
while (i <= mid) {//左边序列剩余
/* for (int k= 0; k <mid-i+1 ; k++) {不需要这样做 temp[t]即可
temp[]
}*/
temp[t] = arr[i];
i++;
t++;
}
while (j <= right) {
temp[t] = arr[j];
t++;
j++;
}
//temp拷贝到arr,并不是拷贝所有
t = 0;
int templeft = left;
while (templeft <= right) {
arr[templeft] = temp[t];
t++;
templeft += 1;
}
}
}
二、基数
基数排序:因为0-9,所以创建10个桶(数组),按照待排序数组数据个位数的大小,对应放入桶中(即数组),如15,325 放在5桶中,对应新开辟的数组下标5。按照顺序重新放入原来数组中。第二轮:按照待排序数组数据十位数的大小,依次类推。。。直到完成最大位的数据的放桶,生成。
代码实现:详情思路见代码注释
package test.sort;
import java.util.Arrays;
/**
* @author shkstart
* @create 2021-01-10 20:07
*/
public class Redix {
public static void main(String[] args) {
int[] arr = {53, 3, 542, 748, 14, 214};
radixSort(arr);
}
public static void radixSort(int[] arr) {//定义一个二维数组,10个桶,每个桶是一维数组,装数据
//0、定义桶的数组、桶中放的个数的数组
int[][] bucket = new int[10][arr.length];
//为了记录存放的数据,bucketelement[0]记录bucket[0]中的个数
int[] bucketElementCounts = new int[10];
//1、记录最大的是百位,个位还是十位
int max = 0;
for (int k = 0; k < arr.length; k++) {
if (arr[k] > max) {
max = arr[k];
}
}
int maxlength = (max + "").length();
//放桶操作
for (int k = 0,n=1; k <maxlength; k++,n*=10) {
k=0,第一轮,针对个位,放入桶中
for (int j = 0; j < arr.length; j++) {
int digitOfElement = arr[j] /n % 10;//个位
//放入对应的桶中
bucket[digitOfElement][bucketElementCounts[digitOfElement]] = arr[j];
bucketElementCounts[digitOfElement]++;//记录该桶的个数
}
//按照这个桶的顺序,放入原来数组
int index = 0;
for (int i = 0; i < bucket.length; i++) {//i<10
if (bucketElementCounts[i] != 0) {//桶中有数据
for (int j = 0; j < bucketElementCounts[i]; j++) {
// arr[i] = bucket[i][j];//不可以arr[i]
arr[index] = bucket[i][j];
index++;
}
}
//第二轮前,个数清零
bucketElementCounts[i] = 0;
}
System.out.println(Arrays.toString(arr));//第二轮....同理 ,k=1
}
}
}