JAVA实践归并排序
来源:互联网 发布:json在线格式化 php 编辑:程序博客网 时间:2024/05/29 04:52
前言
参考书籍:
《数据结构与算法分析·C语言描述》
《算法·第4版》
归并排序只有两大难点,一是分,二是并。
合并
static void merge(int[] a, int low, int mid, int high) { int i = low, j = mid + 1; for (int k = low; k <= high; k++) { aux[k] = a[k]; } for (int k = low; k <= high; k++) { if (i > mid) a[k] = aux[j++]; else if (j > high) a[k] = aux[i++]; else if (aux[i] > aux[j]) a[k] = aux[j++]; else a[k] = aux[i++]; } }
上面这是合并的代码,其中aux是对原始数据的备份,a是我们需要归并的数组。
假设我们有数组
int a = new int[]{3, 6, 4, 5}
那我们传入的参数是merge(a, 0, 1, 3);
四个参数中,mid表示以其为界,左边和右边的数组都是有序的。
[3, 6] | [4, 5]
进行合并操作时,我们分别选取两个数组的第一个元素来比较,然后取较小者。
即代码中
int i = low, j = mid + 1;
以及
for (int k = low; k <= high; k++) { if (i > mid) a[k] = aux[j++]; else if (j > high) a[k] = aux[i++]; else if (aux[i] > aux[j]) a[k] = aux[j++]; else a[k] = aux[i++]; }
从第一个元素low到最后一个元素high进行归并操作,i和j会有四种情况。
分别是左边数组元素已经取尽、右边数组元素已经取尽、左边数组元素大于右边数组元素、左边数组元素小于右边数组元素。
拆分
拆分用递归实现还是比较简单的,只需要计算中间的位置在哪,然后通过参数调整即可。
static void mergeSort(int[] a, int low, int high) { if (low >= high) { return; } int mid = low + (high - low) / 2; //拆分左边 mergeSort(a, low, mid); //拆分右边 mergeSort(a, mid + 1, high); //merge(a, low, mid, high); }
完整代码
public class MergeDemo { //产生测试数据的个数 static int maxNum = 200000; static int[] testData = new int[maxNum]; static int[] aux = new int[maxNum]; static void init() { for (int i = 0; i < maxNum; i++) { testData[i] = (int) (Math.random() * maxNum + 1); } } public static void main(String[] args) { long start, end; init(); int[] a = testData.clone(); start = System.currentTimeMillis(); mergeSort(a); end = System.currentTimeMillis(); System.out.println(end - start + "ms"); } static void mergeSort(int[] a) { sort(a, 0, a.length - 1); } static void sort(int[] a, int low, int high) { if (low >= high) { return; } int mid = low + (high - low) / 2; sort(a, low, mid); sort(a, mid + 1, high); merge(a, low, mid, high); } static void merge(int[] a, int low, int mid, int high) { int i = low, j = mid + 1; for (int k = low; k <= high; k++) { aux[k] = a[k]; } for (int k = low; k <= high; k++) { if (i > mid) a[k] = aux[j++]; else if (j > high) a[k] = aux[i++]; else if (aux[i] > aux[j]) a[k] = aux[j++]; else a[k] = aux[i++]; } }}
结果
66ms
最后,归并排序是可以用插入排序优化的,但是,我尝试的优化在数量级为百万级别时,就少那么几十毫秒,而当数字达到千万级别时,更耗时了。。可能是学艺不精,就不贴代码了。
END
0 0
- JAVA实践归并排序
- 常见算法之归并排序java实践
- java排序--归并排序
- 排序-归并排序-Java
- 归并排序Java实现
- java归并排序算法
- JAVA归并排序算法
- java归并排序
- java归并排序
- Java实现归并排序
- 归并排序(java)
- 25、JAVA归并排序
- java 归并排序
- java归并排序
- Java归并排序
- 归并排序 java
- Java实现归并排序
- 归并排序Java实现
- 让互联网营销发挥百分百效果的方法!全在这里
- Java内存泄露原因详解
- ScroView布局不能撑满全屏
- IOS入职一个月
- codeforces 218D Choosing Capital for Treeland 树形DP
- JAVA实践归并排序
- iOS中block实现的底层探究2
- Ubuntu 14.04 安装Go Git Server
- Android Camera的使用
- jieba分词并写入到TXT文本中
- 经济学原理(第1部分)第二章—11
- iOS--触摸事件的传递
- iOS - 如何去除tabbar顶部线条及设置背景图片
- thinkphp控制器实现隐藏文件路径下载