归并排序
2015-11-15 22:38
344 查看
归并算法的是分治思想的一种体现。
归并算法的主要过程分为两步,首先是对需要排序的元素进行分组,首先一分为二(组),然后二分为四(组),在之后四分为八(组),将元素不断的划分,知道每组元素只包括两个,(当然如果需要排序的元素为奇数个,那么必定是有一组元素只包含的一个的)。我们划分之后,在每组元素之内排序,每个小组的元素有序之后,第二部就开始合并,合并的过程中保证两个合并之后分组是有序的。直到最后八合为四,四合为二,二合为一。
归并排序的算法是稳定的。时间复杂度为 n*log2n
(注:图片来自于百度百科)
下面是实现的代码:
归并算法的主要过程分为两步,首先是对需要排序的元素进行分组,首先一分为二(组),然后二分为四(组),在之后四分为八(组),将元素不断的划分,知道每组元素只包括两个,(当然如果需要排序的元素为奇数个,那么必定是有一组元素只包含的一个的)。我们划分之后,在每组元素之内排序,每个小组的元素有序之后,第二部就开始合并,合并的过程中保证两个合并之后分组是有序的。直到最后八合为四,四合为二,二合为一。
归并排序的算法是稳定的。时间复杂度为 n*log2n
(注:图片来自于百度百科)
下面是实现的代码:
package com.neway.sort; /** * Created by Neway on 2015/11/15. */ public class MergeSort implements Sort { public static void main(String args[]) { Sort sort = new MergeSort(); int arr[] = {89, 78, 8, 5, 13, 12, 11, 1, 0}; sort.sort(arr); } @Override public void sort(int[] arr) { divide(arr, 0, arr.length - 1); } /** * 分割数组 * @param arr 需要排序的数组 * @param start 被分割的那个分组的起点 * @param end 被分割的那个分组的末端 */ public void divide(int[] arr, int start, int end) { /** * 如果当前的分组了内只有一元素或者有两个元素,那么我们排序好了之后返回 */ if (start == end || end - start == 1) { if (arr[start] > arr[end]) { int temp = arr[start]; arr[start] = arr[end]; arr[end] = temp; } return; } /** * 如果分组的长度大于1,那就继续分组, * 根据待排数组的长度,mid 的值略有不同 * */ int mid = -1; if ((end + start) % 2 != 0) { mid = (int) Math.floor((end + start) >> 1); } else { mid = (end + start) >> 1; } // 递归调用分组 divide(arr, start, mid); divide(arr, mid + 1, end); //分完组之后开始合并 merge(arr, start, mid, end); for (int i : arr) { System.out.print(i + " "); } System.out.println(); } /** * 合并两个分组(合并的写法有点繁琐,应该是可以继续优化的) * @param arr 需要排序的数组 * @param start 第一个分组的起点 * @param mid 第一个分组的末端,第二个分组的起点是 mid + 1 * @param end 第二个分组的末端 */ public void merge(int[] arr, int start, int mid, int end) { int startCopy = start; int midCopy = mid; int[] arrCopy = new int[end - start + 1]; int index = 0; while (start <= midCopy && (mid + 1) <= end) { if (arr[start] < arr[mid + 1]) { arrCopy[index++] = arr[start]; start++; } else { arrCopy[index++] = arr[mid + 1]; mid++; } } while (start <= midCopy) { arrCopy[index++] = arr[start++]; } while ((mid + 1) <= end) { arrCopy[index++] = arr[mid + 1]; mid++; } for (int i = 0; i < arrCopy.length; i++) { arr[startCopy++] = arrCopy[i]; } } }
相关文章推荐
- 在命令行用 sort 进行排序
- 动易2006序列号破解算法公布
- 文件遍历排序函数
- 用VBScript写合并文本文件的脚本
- C#选择排序法实例分析
- oracle列合并的实现方法
- Ruby实现的矩阵连乘算法
- C#插入法排序算法实例分析
- 使用BAT一句话命令实现快速合并JS、CSS
- C#实现Datatable排序的方法
- SQL 合并多行记录的方法总汇
- C#实现简单合并word文档的方法
- 超大数据量存储常用数据库分表分库算法总结
- SQLSERVER的排序问题结果不是想要的
- Windows Powershell排序和分组管道结果
- C#数据结构与算法揭秘二
- C#冒泡法排序算法实例分析
- C#自适应合并文件的方法
- C#通过IComparable实现ListT.sort()排序