前言
小编最近学习到了归并排序,下面就与小编一起看看归并排序到底是什么?
是什么
归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
算法思路,将大问题化解为一个个小问题,通过解决小问题来解决大问题
代码展示
public class MergeSort {
/**
* 将分区的数组进行排序
*/
public static void merge(int[] a, int start, int mid, int end) {
int[] tmp = new int[a.length];
System.out.println("排序区间 " + start + "~" + end);
int i = start, j = mid + 1, k = start;
while (i != mid + 1 && j != end + 1) {
//将数组排序,并将排序后的结果赋值给tmp[]
if (a[i] < a[j]) {
tmp[k++] = a[i++];//将左边分组赋值给tmp[]
} else {
tmp[k++] = a[j++];//将右边分组赋值给tmp[]
}
}
while (i != mid + 1) {
tmp[k++] = a[i++];//将剩余部分(左边分组)赋值给tmp[]数组
}
while (j != end + 1) {
tmp[k++] = a[j++];//将剩余部分(右边分组)赋值给tmp[]数组
}
for (i = start; i <= end; i++) {
a[i] = tmp[i];//tmp[]数组重新赋值给a[]数组
}
for (i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
System.out.println();
}
/**
* 将待排数组进行分区
*/
static void mergeSort(int[] a, int start, int end) {
if (start < end) {
int mid = (start + end) / 2;// 一分为二(分治法)
mergeSort(a, start, mid);// 左边分组
mergeSort(a, mid + 1, end);// 右边分组
merge(a, start, mid, end);// 调用排序逻辑
}
}
public static void main(String[] args) {
int[] b = { 8,4,5,7,1,3,6,2 };
mergeSort(b, 0, b.length - 1);
}
}
对代码理解的不是很清楚?通过图来看,搭配着图(图是老车的)来理解,下面是分治的过程
这里是排序的的过程,也就是部分归并的过程,另一部分与此相似,就不重复展示了
什么?什么?还是不理解?没关系,咱们把代码在原来的基础上稍微修改一下就行了
整理后的代码
public class MergeSort {
/**
* 将分区的数组进行排序
*/
public static void merge(int[] a, int start, int mid, int end,int[] tmp) {
int i = start, j = mid + 1, k = start;
while (i != mid + 1 && j != end + 1) {
if (a[i] < a[j]) {//将数组排序
tmp[k++] = a[i++];
} else {
tmp[k++] = a[j++];
}
}
while (i != mid + 1) {
tmp[k++] = a[i++];//将左边分组赋值给tmp[]数组
}
while (j != end + 1) {
tmp[k++] = a[j++];//将右边分组赋值给tmp[]数组
}
for (i = start; i <= end; i++) {
a[i] = tmp[i];//将tmp[]数组重新赋值给a[]数组
}
System.out.println("排序后的a数组");
for (i = 0; i < a.length; i++) {
System.out.print(a[i] + " ");
}
System.out.println();
}
/**
* 将待排数组进行分区
*/
static void mergeSort(int[] a, int start, int end, int T[]) {
if (start < end) {
int mid = (start + end) / 2;// 一分为二(分治法)
mergeSort(a, start, mid,T);// 左边分组
System.out.println("左边");
System.out.println("开始下标start是"+" "+ start+" "+"结束下标mid是"+" "+ mid);
System.out.println("排序前a数组");
for (int p : a) {
System.out.print(p + " ");
}
System.out.println();
System.out.println("排序后tmp数组");
for (int w : T) {
System.out.print(w + " ");
}
System.out.println();
mergeSort(a, mid + 1, end,T);// 右边分组
System.out.println("右边");
System.out.println("开始下标mid+1是"+" "+(mid+1)+" "+"结束下标end是"+" "+ end);
System.out.println("排序前a数组");
for (int p : a) {
System.out.print(p + " ");
}
System.out.println();
System.out.println("排序后tmp数组");
for (int w : T) {
System.out.print(w + " ");
}
System.out.println();
merge(a, start, mid, end,T);// 调用排序逻辑
}
}
public static void main(String[] args) {
int[] b = { 5, 8, 9, 6, 7, 1, 3, 4 };
int[] T=new int[b.length];
int c=b.length-1;
mergeSort(b, 0, b.length - 1,T);
}
}
输出结果
左边
开始下标start是 0 结束下标mid是 0
排序前a数组
8 4 5 7 1 3 6 2
排序后tmp数组
0 0 0 0 0 0 0 0
右边
开始下标mid+1是 1 结束下标end是 1
排序前a数组
8 4 5 7 1 3 6 2
排序后tmp数组
0 0 0 0 0 0 0 0
排序后的a数组
4 8 5 7 1 3 6 2
左边
开始下标start是 0 结束下标mid是 1
排序前a数组
4 8 5 7 1 3 6 2
排序后tmp数组
4 8 0 0 0 0 0 0
左边
开始下标start是 2 结束下标mid是 2
排序前a数组
4 8 5 7 1 3 6 2
排序后tmp数组
4 8 0 0 0 0 0 0
右边
开始下标mid+1是 3 结束下标end是 3
排序前a数组
4 8 5 7 1 3 6 2
排序后tmp数组
4 8 0 0 0 0 0 0
排序后的a数组
4 8 5 7 1 3 6 2
右边
开始下标mid+1是 2 结束下标end是 3
排序前a数组
4 8 5 7 1 3 6 2
排序后tmp数组
4 8 5 7 0 0 0 0
排序后的a数组
4 5 7 8 1 3 6 2
左边
开始下标start是 0 结束下标mid是 3
排序前a数组
4 5 7 8 1 3 6 2
排序后tmp数组
4 5 7 8 0 0 0 0
左边
开始下标start是 4 结束下标mid是 4
排序前a数组
4 5 7 8 1 3 6 2
排序后tmp数组
4 5 7 8 0 0 0 0
右边
开始下标mid+1是 5 结束下标end是 5
排序前a数组
4 5 7 8 1 3 6 2
排序后tmp数组
4 5 7 8 0 0 0 0
排序后的a数组
4 5 7 8 1 3 6 2
左边
开始下标start是 4 结束下标mid是 5
排序前a数组
4 5 7 8 1 3 6 2
排序后tmp数组
4 5 7 8 1 3 0 0
左边
开始下标start是 6 结束下标mid是 6
排序前a数组
4 5 7 8 1 3 6 2
排序后tmp数组
4 5 7 8 1 3 0 0
右边
开始下标mid+1是 7 结束下标end是 7
排序前a数组
4 5 7 8 1 3 6 2
排序后tmp数组
4 5 7 8 1 3 0 0
排序后的a数组
4 5 7 8 1 3 2 6
右边
开始下标mid+1是 6 结束下标end是 7
排序前a数组
4 5 7 8 1 3 2 6
排序后tmp数组
4 5 7 8 1 3 2 6
排序后的a数组
4 5 7 8 1 2 3 6
右边
开始下标mid+1是 4 结束下标end是 7
排序前a数组
4 5 7 8 1 2 3 6
排序后tmp数组
4 5 7 8 1 2 3 6
排序后的a数组
1 2 3 4 5 6 7 8
这样对比着每一次归并来看代码,会好理解很多,而且每一次的数值变化都可以体现出来
总结
算法是我们本次的学习目标,学习算法的根本目的不仅仅是算法,重要的是体会到这种算法的本质思想,它解决问题的方式等,好了,本次归并排序就到这里了,哪里不理解可以在博客下面留言,感谢您的阅读