递归和非递归实现归并排序
2017-04-26 18:23
246 查看
1、递归实现归并排序
递归排序其实也是利用了完全二叉树的结构形式,所以时间复杂度和logN挂钩的。具体递归版的归并排序呢,看下面的代码:
运行结果如下:
2、非递归实现归并排序
由于递归的过程中要用到栈,那么这无疑会增加额外的时间和空间消耗,因此,在选择时,有限选择非递归版的归并算法。具体代码如下:
运行结果如下:
以上就是关于归并排序的程序部分,望共享。
递归排序其实也是利用了完全二叉树的结构形式,所以时间复杂度和logN挂钩的。具体递归版的归并排序呢,看下面的代码:
public class MS { public static void main(String[] args) { int[] s = new int[] { 5, 3, 6, 2, 1, 9, 4, 8, 7 }; print(s); mergeSort(s); System.out.println("排序后的数组:"); print(s); } public static void mergeSort(int[] data) { sort(data, 0, data.length - 1); } public static void sort(int[] data, int left, int right) { if (left >= right) return; // 找出中间索引 int center = (left + right) / 2; // 对左边数组进行递归 sort(data, left, center); // 对右边数组进行递归 sort(data, center + 1, right); // 合并 merge(data, left, center, right); print(data); } /** * 将两个数组进行归并,归并前面2个数组已有序,归并后依然有序 * * @param data * 数组对象 * @param left * 左数组的第一个元素的索引 * @param center * 左数组的最后一个元素的索引,center+1是右数组第一个元素的索引 * @param right * 右数组最后一个元素的索引 */ public static void merge(int[] data, int left, int center, int right) { // 临时数组 int[] tmpArr = new int[data.length]; // 右数组第一个元素索引 int mid = center + 1; // third 记录临时数组的索引 int third = left; // 缓存左数组第一个元素的索引 int tmp = left; while (left <= center && mid <= right) { // 从两个数组中取出最小的放入临时数组 if (data[left] <= data[mid]) { tmpArr[third++] = data[left++]; } else { tmpArr[third++] = data[mid++]; } } // 剩余部分依次放入临时数组(实际上两个while只会执行其中一个) while (mid <= right) { tmpArr[third++] = data[mid++]; } while (left <= center) { tmpArr[third++] = data[left++]; } // 将临时数组中的内容拷贝回原数组中 // (原left-right范围的内容被复制回原数组) while (tmp <= right) { data[tmp] = tmpArr[tmp]; tmp++; } } public static void print(int[] data) { for (int i = 0; i < data.length; i++) { System.out.print(data[i] + " "); } System.out.println(); } }
运行结果如下:
5 3 6 2 1 9 4 8 7 3 5 6 2 1 9 4 8 7 3 5 6 2 1 9 4 8 7 3 5 6 1 2 9 4 8 7 1 2 3 5 6 9 4 8 7 1 2 3 5 6 4 9 8 7 1 2 3 5 6 4 9 7 8 1 2 3 5 6 4 7 8 9 1 2 3 4 5 6 7 8 9 排序后的数组: 1 2 3 4 5 6 7 8 9
2、非递归实现归并排序
由于递归的过程中要用到栈,那么这无疑会增加额外的时间和空间消耗,因此,在选择时,有限选择非递归版的归并算法。具体代码如下:
package 排序; //非递归实现归并排序 public class NewMS { public static void main(String[] args) { int[] s = new int[] { 5, 3, 6, 2, 1, 9, 4, 8 ,7}; print(s); MergeSort2(s); System.out.println("排序后的数组:"); print(s); } private static void MergeSort2(int[] s) { //该函数的作用是让数组中的元素以k进行变步长迭代 int k=1; while(k<s.length){ MergePass(s,k,s.length-1); //MergePass函数的作用是在给定步长k的情况下,实现局部合并 k=2*k; //k是以1、2、4、8、16为步长的,当然16步长无法实现 } } private static void MergePass(int[] s, int k, int len) { int i=0; while(i<=len-2*k+1){//此处循环的目的是两两归并 Merge(s,i,i+k-1,i+2*k-1); i=i+2*k; print(s); } if(i<len-k+1){//判断是否有落单的数据,如果有的话直接将其和前面相邻的一组数据进行归并 Merge(s,i,i+k-1,len); print(s); } } private static void Merge(int[] s, int left, int m, int right) {//此部分为归并代码块 int[] tmp=new int[s.length]; int k=left; int third=left; int j=m+1; while(left<=m&&j<=right){ if(s[left]<s[j]){ tmp[k++]=s[left++]; }else{ tmp[k++]=s[j++]; } } while(left<=m){ tmp[k++]=s[left++]; } while(j<=right){ tmp[k++]=s[j++]; } while(third<=right){ s[third]=tmp[third]; third++; } } private static void print(int[] s) { for(int i=0;i<s.length;i++){ System.out.print(s[i]+" "); } System.out.println(); } }
运行结果如下:
5 3 6 2 1 9 4 8 7 3 5 6 2 1 9 4 8 7 3 5 2 6 1 9 4 8 7 3 5 2 6 1 9 4 8 7 3 5 2 6 1 9 4 8 7 2 3 5 6 1 9 4 8 7 2 3 5 6 1 4 8 9 7 1 2 3 4 5 6 8 9 7 1 2 3 4 5 6 7 8 9 排序后的数组: 1 2 3 4 5 6 7 8 9
以上就是关于归并排序的程序部分,望共享。
相关文章推荐
- 归并排序非递归实现C语言
- 归并排序(递归实现+非递归实现+自然合并排序)
- 归并排序的递归实现与非递归实现代码
- Shell、归并排序、递归的java实现
- 归并排序(递归实现)- 数据结构和算法94
- 两种归并排序算法的实现:二路归并排序和基本归并排序(虚拟消除递归的二路归并排序)
- 链表的归并排序(经典实现:递归)
- 常用排序算法完全版 快排优化 归并排序的非递归实现
- <转> - 归并排序(递归实现+非递归实现+自然合并排序)
- Python归并排序(递归实现)
- 递归实现归并排序(基本排序算法)
- 用Java泛型实现归并排序(递归和非递归算法)
- 继续算法课的学习!归并排序的模版函数的递归实现(merge函数用两个来实现,记得检查左右边界指针的范围哦)
- 归并排序的递归实现与非递归实现
- 非递归实现归并排序
- 递归到非递归转换——归并排序与快排的非递归实现
- 归并排序的递归和非递归实现(C代码)
- 归并排序(递归和非递归方法实现)
- 归并排序的非递归实现
- 数组的归并排序(经典实现:使用Ο(n)的辅助空间,递归)