本文我准备用Java实现归并排序。具体的排序算法过程已经在注释里面了,大家可以复制代码到IDE里面,用DEBUG模式研究算法的过程(算法参考:https://blog.csdn.net/qq_36442947/article/details/81612870):
import java.util.Arrays;
import java.util.Random;
/**
* @author LiYang
* @ClassName MergeSort
* @Description 归并排序算法
* @date 2019/11/4 16:50
*/
public class MergeSort {
/**
* 归并排序算法(MergeSort)
* 本算法会分解数组到左右都只有1个元素的子数组(肯定有序),
* 然后归并为2个元素的子数组(已经有序),然后又归并为
* 4个元素的子数组(已经有序)……直到全部待排序数组
* @param arr 待排序的数组
* @param left 起始下标
* @param right 终止下标
*/
public static void mergeSort(int [] arr, int left, int right){
//当子序列中只有一个元素时,也就是left = right时,结束递归
if(left < right){
//将当前数组分为两个子数组的分界线
int mid = (left + right) / 2;
//对左侧子数组进行递归归并排序
mergeSort(arr, left, mid);
//对右侧子数组进行递归归并排序
mergeSort(arr, mid + 1, right);
//归并左右侧子序列
merge(arr, left, mid, right);
}
}
/**
* 归并排序算法的归并操作,将两个有序数组归并为一个排序数组
* @param arr 归并前的数组,包含左右两个有序数组
* @param left 左边界
* @param mid 两个有序数组的分隔下标
* @param right 右边界
*/
public static void merge(int[] arr, int left, int mid, int right){
//左边数组检测的下标
int leftIndex = left;
//右边数组检测的下标
int rightIndex = mid + 1;
//归并后的数组的下标
int mergeIndex = left;
//归并排序装归并结果的数组
int [] mergeArray = new int[arr.length];
//当左数组和右数组都未到最右边
while(leftIndex <= mid && rightIndex <= right){
//如果左数组的元素小于等于右数组的元素
if(arr[leftIndex] <= arr[rightIndex]) {
//将左数组的元素放入归并后的数组,左数组index + 1
mergeArray[mergeIndex++] = arr[leftIndex++];
//如果左数组元素大于右数组元素
} else {
//将右数组的元素放入归并后的数组,右数组index + 1
mergeArray[mergeIndex++] = arr[rightIndex++];
}
}//本while循环结束,左右数组至少有一个遍历结束
//如果左数组没有遍历结束
while(leftIndex <= mid){
//将左数组剩下的元素依次放入归并后的数组
mergeArray[mergeIndex++] = arr[leftIndex++];
}
//如果右数组没有遍历结束
while(rightIndex <= right){
//将右数组剩下的元素依次放入归并后的数组
mergeArray[mergeIndex++] = arr[rightIndex++];
}
//将归并后的有序数组,复制代替原来的数组
for (int i = left; i <= right; i++){
arr[i] = mergeArray[i];
}
}
/**
* 归并排序(MergeSort)的驱动程序
* @param arr 待排序的数组
*/
public static void mergeSort(int[] arr){
//归并排序的左边界
int left = 0;
//归并排序的右边界
int right = arr.length - 1;
//调用归并排序的方法
mergeSort(arr, left, right);
}
/**
* 验证归并排序算法
* @param args
*/
public static void main(String[] args) {
//待排序数组
int[] arr = new int[30];
//随机数类
Random random = new Random();
//随机生成排序数组(100以内的整数)
for (int i = 0; i < arr.length; i++) {
arr[i] = random.nextInt(100);
}
//打印待排序数组
System.out.println("归并排序前:" + Arrays.toString(arr));
//进行归并排序(调用驱动程序,就是只有一个参数的mergeSort()方法)
mergeSort(arr);
//打印归并排序后的数组
System.out.println("归并排序后:" +Arrays.toString(arr));
}
}
运行 MergeSort 类的main方法,归并排序算法测试通过:
归并排序前:[33, 39, 17, 51, 8, 28, 92, 93, 30, 52, 25, 45, 36, 52, 4, 89, 67, 23, 42, 29, 59, 50, 18, 82, 37, 59, 32, 48, 12, 51]
归并排序后:[4, 8, 12, 17, 18, 23, 25, 28, 29, 30, 32, 33, 36, 37, 39, 42, 45, 48, 50, 51, 51, 52, 52, 59, 59, 67, 82, 89, 92, 93]