【归并排序】基础代码
🍋前言
最近在学习分治法,涉及到之前学习的归并排序,当时学习数据结构的时候就归并排序背后的内容没有深究,过去留下的问题,在现在的使用中展现出不足,写下一些学习中的总结和思考,认真探讨归并排序。
🤔算法思想
归并排序是是分治法思想的典型代表,根据分治法的思想可以分为以下过程
1.划分:将待排序序列划分1n划分成为两个长度相等的子序列1n/2和n/2+1到n
2.求解子问题:分别对这两个子序列进行排序,的到两个有序的子序列
3.合并:将这两个有序子序列合并成一个有序序列
⭐️如何代码实现
首先要将原始的序列划分成为两个子序列,对于划分后的左右序列也要采用同样的策略进行划分,因此可以采用递归的方式去调用,当划分到的序列只有一个记录的时候,算是递归出口(因为一个记录本身就是有序的),划分的结果是将n个记录的待排序序列划分成n个长度为1的有序子序列;接下来需要进行合并操作,合并的时候由于是在原数组上进行排序操作,需要一个辅助数组来暂存当前排序好的元素,合并是对当前的两个子序列进行合并,基本思路和数据结构中的合并两个有序数组一样,通过由1个记录之间的合并到整个左序列和整个右序列之间的合并,最后得到的就是排序好的序列。
💻代码
package LOQ.排序;
import java.util.Arrays;
import java.util.Scanner;
/*
归并排序
*/
public class MergeSort {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Please input array length:");
int len = sc.nextInt();
System.out.println("please input array element:");
int[] arr = new int[len];
for(int i=0;i<len;i++) {
arr[i]=sc.nextInt();
}
mergeSort(arr,0,arr.length-1);
System.out.println(Arrays.toString(arr));
}
//拆分数组,成为单个有序的
private static void mergeSort(int[] arr,int low,int high) {
//当low==high的时候,只有一个元素,所以不需要排序
if(low<high) {
//得到中间值,把原来的数组分成两部分
int mid = (low+high)/2;
//递归调用左半部分进行分组
mergeSort(arr,low,mid);
//递归调用右半部分进行分组
mergeSort(arr,mid+1,high);
//合并左半部分和右半部分
merge(arr,mid,low,high);
}
}
//合并左半部分和右半部分
private static void merge(int[] arr,int mid,int low,int high) {
//记录左区域的第一个值
int lPot = low;
//记录右区域的第一个值
int hPot = mid+1;
//临时数组的起始值,也就是low
int start = 0;
//合并的临时数组
int[] temp = new int[high-low+1];
//合并两个有序序列
while(lPot<=mid && hPot<=high) {
//左区域第一个元素小于右区域第一个元素
if(arr[lPot]<arr[hPot]) {
temp[start++] = arr[lPot++];
} else {
temp[start++] = arr[hPot++];
}
}
//合并左区域剩余元素
while(lPot<=mid) {
temp[start++] = arr[lPot++];
}
//合并右半区域元素
while(hPot<=high) {
temp[start++] = arr[hPot++];
}
//覆盖原数组空间
for(int i=0;i<temp.length;i++) {
arr[i+low] = temp[i];
}
}
}
🙈结尾
这里列举的只是2路归并排序,算法描述的还不够清晰,还有代码优化也没有实现,等有时间再补充其他内容。
2022年3月11日15:44:11