排序算法之归并排序
前2段是废话可直接看第3段,coding多年一些常见算法及原理还是记得的,平时习惯了IDE去 “.” 出一些方法,在跳槽面试中让编写算法及优化时也是抓瞎,其实算法原理应该是上动态图片更直观些的,无奈曾经遇到过大神制作的动图没有保存,自己又比较笨拙不会制作,但文章结尾会贴出本人参照较好的文章供大家一起分析。
在此也声明下,本人学习期间会参照一些老师及大神的书籍或博客,个人认为我不懂就要和懂的人学习知识并吸收总结成自己的,这其实没有什么丢人的,所以博客、代码均通过收集资料分析、编写、优化、测试及总结整理后书写博客与大家分享,目的在于自我加深印象,分享及传播知识。希望大家就实际问题相互学习探讨,请勿互掐。
归并排序:主要采用分而治之的方法,将数组从中分割开2部分,1变2,2变4,4变8…分割至不能分割,后在进行合并时排序,可参照参考博客[1] 的图解,可参照参考博客[2] 的动图。
直接上测试代码:
import java.util.Arrays;
/**
* @Author: Wenx
* @Description: 归并排序
* @Date: Created in 2020/3/7 8:41
* @Modified By:
*/
public class MergeSort<T extends Comparable<T>> implements Sort<T> {
@Override
public void sort(T[] values) {
int size = values.length;
int low = 0;
int high = size - 1;
sort(values, low, high);
}
private void sort(T[] values, int low, int high) {
if (low < high) {
// 获取中间索引
int mid = (low + high) / 2;
// 拆分左半部分
sort(values, low, mid);
// 拆分右半部分
sort(values, mid + 1, high);
// 合并两部分
merge(values, low, mid, high);
}
}
private void merge(Comparable<T>[] values, int low, int mid, int high) {
// 计算两部分各自元素数量
int n1 = mid - low + 1;
int n2 = high - mid;
Comparable[] a1 = new Comparable[n1];
Comparable[] a2 = new Comparable[n2];
// 复制到新数组
System.arraycopy(values, low, a1, 0, n1);
System.arraycopy(values, mid + 1, a2, 0, n2);
int index = low;
int i = 0, j = 0;
while (i < n1 && j < n2) {
// 循环比较两数组元素大小,小的放进源数组
if (a1[i].compareTo(a2[j]) == -1) {
values[index++] = a1[i++];
} else {
values[index++] = a2[j++];
}
}
// 将剩下的依次放进源数组
while (i < n1) {
values[index++] = a1[i++];
}
// 将剩下的依次放进源数组
while (j < n2) {
values[index++] = a2[j++];
}
}
public static void main(String[] args) {
Integer[] values = {1, 5, 4, 3, 2, 6, 7, 8, 9};
Sort<Integer> sort = new MergeSort<>();
long startTime = System.nanoTime();
sort.sort(values);
long endTime = System.nanoTime();
System.out.printf("耗时:%d ns, %s\n", endTime - startTime, Arrays.toString(values));
}
}
留个接口方便后续操作:
/**
* @Author: Wenx
* @Description: 排序接口
* @Date: Created in 2020/3/5 17:15
* @Modified By:
*/
public interface Sort<T extends Comparable<T>> {
void sort(T[] values);
}
总结:重点在于理解原理,使之变为自己的知识,编码可参照众多实现形式,每个人理解及想法均有差异,结合他人及自己想法转化实践就好了~
参考博客:
[1] https://www.cnblogs.com/chengxiao/p/6194356.html
[2] https://blog.youkuaiyun.com/dp_dp/article/details/80543290