排序算法之2路归并排序(递归和非递归)

归并排序,从字面意思上理解,即合并的时候排序。

归并排序是分治法的一种,首先将待排数列分成1个一个元素,然后依次按大小合并。

排序过程


初始关键值  [49]  [38]  [65]  [97]  [76]  [13]  [27] 

合                         

第一趟归并:(38,49)   (65,97)    (13,76)     27

第三趟归并:(38,49,65,97)         (13,27,76)

第四趟合并:[13,27,38,49,65,76,97]


代码:

package merge;


import java.util.Arrays;


public class MergeSort {
public static void main(String[] args) {
int x[]={4,-5,0,3,-1,12,9,-7,8,-4,11};  
int []a = new int[]{33,9,34,12,6,10,8,9,32,1};
int[] b = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11 };
MergeSort sort = new MergeSort();
sort.NMergeSort(x);
System.out.println(Arrays.toString(x));
sort.mergeSort(a, 0, a.length - 1);
System.out.println(Arrays.toString(a));
System.out.println();
sort.mergeSort(b,0,a.length - 1);
System.out.println(Arrays.toString(b));
}
public void merge(int []a,int low,int middle,int high){//合并
int length = a.length;//将low到Middle ,Middle到high的元素按顺序合并
int []b = new int[length];//辅助数组
int k = 0;
int j = middle+1,i = low;
while(i <= middle && j <=high){
if(a[i]<a[j]) b[k++] = a[i++];//比较较小者填入数组
else b[k++] = a[j++];
}
while(i <= middle) b[k++] = a[i++];//若有元素没有填入完
while(j <= high) b[k++] = a[j++];

for(k = 0,i = low;i <= high;i++,k++){
a[i] = b[k];//将数组重新复制到a数组中
}
}
/**
* 非递归
*/
public void NMergeSort(int []a){
int size=1;//分治元素数量初始为1,按2的幂次递增
int length = a.length;
int low = 0;
int middle;
int high;
while(size < length){
//分治
low = 0;
while(low + size <= length-1){
middle = low + size - 1;//合并左边高位下标
high = middle + size;//带合并右边数组高位下标
if(high > length - 1){//如果右边数组中的数值不够size
high = length - 1;
}
merge(a,low,middle,high);//按size合并
low = high+1;//递增遍历整个数组
}
size*=2;
}
}
/**
* 递归
*/
public void mergeSort(int a[],int low,int high){
int middle;
if(low == high) return ;
else{
middle = (low+high)/2;
mergeSort(a, low, middle);//先分治
mergeSort(a,middle+1,high);
merge(a,low,middle,high);//再合并
}
}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
归并排序是一种经典的排序算法,它采用分治的思想,将一个大问题分解成若干个小问题,然后合并小问题的解来得到大问题的解。归并排序递归实现非常简单,但实际上我们也可以使用非递归的方式来实现归并排序非递归归并排序算法可以使用迭代的方式来实现。具体的实现是,先将原组分成若干个长度为1的子组,然后将相邻的子组合并成长度为2的子组,再将相邻的长度为2的子组合并成长度为4的子组,以此类推,直到将整个组排好序为止。 下面是归并排序非递归算法的代码实现: ```python def merge_sort(arr): n = len(arr) step = 1 while step < n: for i in range(0, n, step * 2): left = i right = min(i + step, n) end = min(i + step * 2, n) merge(arr, left, right, end) step *= 2 return arr def merge(arr, left, right, end): left_arr = arr[left:right] right_arr = arr[right:end] k = left i = j = 0 while i < len(left_arr) and j < len(right_arr): if left_arr[i] <= right_arr[j]: arr[k] = left_arr[i] i += 1 else: arr[k] = right_arr[j] j += 1 k += 1 while i < len(left_arr): arr[k] = left_arr[i] i += 1 k += 1 while j < len(right_arr): arr[k] = right_arr[j] j += 1 k += 1 ``` 在上面的代码中,`merge_sort` 函使用一个变量 `step` 来表示当前合并的子组的长度,初始值为1。然后在一个 `while` 循环中,每次将相邻的两个长度为 `step` 的子组合并成一个长度为 `step*2` 的子组,直到 `step` 大于等于组长度为止。在合并子组的时候,我们使用 `merge` 函将两个子组合并成一个有序的子组。 需要注意的是,在 `merge` 函中,我们使用了一个 `left` 变量来表示左子组的起始位置,使用一个 `right` 变量来表示右子组的起始位置,使用一个 `end` 变量来表示右子组的结束位置。这是因为在合并子组的时候,右子组的起始位置并不是固定的,而是根据 `left` 和 `step` 来计算的。 归并排序非递归实现虽然比递归实现稍微复杂一些,但它具有更好的空间复杂度和更好的稳定性,是一种非常实用的排序算法

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值