归并排序
来源:互联网 发布:mac系统桌面文件路径 编辑:程序博客网 时间:2024/06/06 23:50
归并排序是利用归并的思想实现排序,这里只介绍2路归并排序,其思想是:假设初始待排序队列记录数为n,看成n个长度为1的子序列,然后两两合并,得到个长度为2或1的有序子序列,再两两合并,……, 如此重复直至得到长度为n的有序序列为止。示意图如下。
实现2路归并排序需要额外的与待排序序列大小相同的空间。给出两个有序子序列合并的代码:
/** * 两个有序序列的归并函数 * * @Title: merge * @Description: 将有序的array[begin,...mid]与 * array[mid+1,...,end]归并为assist[begin,...,end],最后复制到array * @param array * 待排序数组 * @param assist * 辅助数据 * @param begin array [begin--------------mid--------------end] * | | 有序 | 有序 | * @param mid | * | * @param end assist [--------------------------------------] * | 有序 | */private void merge(int[] array, int[] assist, int begin, int mid, int end){int i, j, k;for (i = begin, j = mid + 1, k = begin; (i < mid + 1) && (j <= end); k++){if (array[i] < array[j]){assist[k] = array[i++];} else{assist[k] = array[j++];}}if (i < mid + 1) {for (; i < mid + 1;){assist[k++] = array[i++];}}if (j <= end){for (; j <= end;){assist[k++] = array[j++];}}// copySystem.arraycopy(assist, begin, array, begin, (end - begin + 1));}归并排序的递归实现:
/** * 归并排序的实现 * * @Title: mSort * @Description: array借助于assist把下标从begin到end的序列进行归并排序 * @param array * 待排序序列 * @param assist * 辅助序列 * @param begin * 起始下标 * @param end * 结束下标 */private void mSort(int[] array, int[] assist, int begin, int end){int mid;if (begin == end){return;} else{mid = (begin + end) / 2;mSort(array, assist, begin, mid);mSort(array, assist, mid + 1, end);merge(array, assist, begin, mid, end);}}
/** * 归并排序的主函数 * * @Title: mergeSort * @Description: 给定待排序数组进行归并排序 * @param array * 给定待排序数组 */public void mergeSort(int[] array){// assist arrayint[] assist = new int[array.length];// sortmSort(array, assist, 0, array.length - 1);}
非递归实现,其核心思想就是如图所示,第一轮子序列长度为1进行归并,第二轮子序列长度为2进行归并,第三轮子序列长度为4进行归并,····,直至子序列长度大于待排序列的长度。每一轮归并后,剩余序列,分两种情况:1、剩余序列大于当前子序列,则表明剩余有两个序列,进行归并;2、剩余序列小于当前子序列(包括0),则不进行操作。代码如下:
/** * 进行一趟归并排序 * * @Title: mergePass * @Description: 子序列长度为k,对array序列进行一趟归并操作。 * @param array * 待排序序列 * @param assist * 辅助序列 * @param k * 子序列长度 */private void mergePass(int[] array, int[] assist, int k){int index = 0;while (index < array.length - 2 * k + 1){merge(array, assist, index, (index + k - 1), (index + 2 * k - 1));index += 2 * k;}if (index < array.length - k){merge(array, assist, index, (index + k - 1), array.length - 1);}}
/** * 归并排序非递归实现 * * @Title: mergeSortNonRec * @Description: 待排序序列array归并排序的非递归操作 * @param array * 待排序序列 */public void mergeSortNonRec(int[] array){// assistint[] assist = new int[array.length];// sortint k = 1;while (k < array.length){mergePass(array, assist, k);k *= 2;}}
性能分析:
归并排序是一种稳定的排序算法,每趟归并需要所有记录扫描一遍,耗时O(n)时间,而由完全二叉树深度可知,整个归并排序需要进行次,因此总的时间复杂度为
O(nlogn)。非递归实现时归并排序需要与待排序数组相同的存储空间,递归实现除了上述存储空间,还需要深度为的栈。而且归并排序平均情况、最好情况和最坏情况的时间复杂度都为。
所以,归并排序是一种比较占用内存,但却效率高且稳定的排序算法。
- 归并排序-归并排序
- 归并和归并排序
- 归并与归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 排序::归并
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 归并排序
- 世界顶级遥感网站
- MAC系统下PPTP设置VPN上网方法
- 关于Handler二三事(下)
- PS快捷键整理
- 专业程序员必知的技巧:敲打代码
- 归并排序
- Android2.2.1广播大全
- 解决VMWare Player 5.0在Ubuntu 12.04中卡的问题
- canvas的IE6.0下的实现
- Linux 系统如何查看系统配置信息
- 人有多大懒,才有多大显
- 获取谷歌地图的密钥 KEY(写于2013年)
- 软件项目总结报告范文
- FaceL:一个靠谱的开源人脸标注训练识别程序