归并排序 2020-09-20


归并算法

通过不断的进行二分法进行分组,直到分到每组只有一个元素以后,进行递归。在递归过程中,每次递归回上一个组别时,每次在执行自身这个组的排序方法之前,都会先将它以下的组别传入到排序方法中,按照有序排序顺序排列好.


一、代码

/**  
 * @param a 需要进行递归的数组
 * @param start 每次递进的左数组开始位置
 * @param right 每次递进的右边数组结束位置
 * @param temp 临时数组
 */
public static void mergeSort(int[] a, int start, int right, int[] temp) {
    //当start不比right小的时候,说明已经分组到了只剩一个了
    if (start < right) {
        int mid = (start + right) / 2;
        //左边递进
        mergeSort(a,start,mid,temp);
        //右边递进
        mergeSort(a,mid + 1, right,temp);
        //归还,第一次执行这里的时候,已经完全分好了
        merge(a, start, mid, right, temp);
    }
}
/**
 * @param a     需要排序的数组
 * @param start 左边一个数组开始的位置
 * @param mid   左边一个数组结束位置
 * @param right   右边一个数组结束位置
 * @param temp  临时数组,用来暂时存放排序好的数组
 */
public static void merge(int[] a, int start, int mid, int right, int[] temp) {
    int t = 0; //记录临时数组的下标
    int l = start; //用来记录左边数组当前位置
    int r = mid + 1; //来记录右边数组的当前位置

    //判断这两个数组是否有一个数组已经遍历完了
    while (l <= mid && r <= right) {
        //看左边的那个数组的当前下标的值是否比后面的大
        if (a[l] < a[r]) {
            //如果大就存入临时数组中
            temp[t] = a[l];
            //让前面的那个数组下标+1,当作遍历
            l++;
            //临时数组下表也要+1
            t++;
        } else {
            //如果比那个小的话
            temp[t] = a[r];
            r++;
            t++;
        }
    }

    //判断左边是否还有残留数据.
    while (l <= mid) {
        temp[t] = a[l];
        t++;
        l++;
    }
    while (r <= right) {
        temp[t] = a[r];
        t++;
        r++;
    }
    //temp每次都是从0开始存的,但a数组不是
    t = 0;
    //将临时数组的值给回原数组
    for (int i = start; i <= right; i++) {
        a[i] = temp[t];
        t++;
    }
}

二、注意

2.1

right的值是随着传入的mid的值进行的改变的,只有(0+1)/2等于0的时候,说明已经分的只有最后一个了.

   //当start不比right小的时候,说明已经分组到了只剩一个了
    if (start < right)

2.2

向左递进的时候会先递进到只有一个元素了才会结束,而这时的mid值是0,right值经过上次传入的mid为1,而这时开始进行向右递进,因此导致了第一次的时候只有两个元素在进行排列.
当左边的第一次归还完成的时候,便会退出返回到上一次递进中,而这次的递进,就只完成了左递进,于是便要完成右递进。而当右递进完成了之后,便开始自己的排序了。
如此往上,因此,每次向大的数组递归的时候,左右两边都已经是有序的了

        //左边递进
        mergeSort(a,start,mid,temp);
        //右边递进
        mergeSort(a,mid + 1, right,temp);
        //归还,第一次执行这里的时候,已经完全分好了
        merge(a, start, mid, right, temp);

2.2

start和right是用来确定a数组中具体排列的位置的。

//temp每次都是从0开始存的,但a数组不是,每次都是是分一点合一点
t = 0;
//将临时数组的值给回原数组
for (int i = start; i <= right; i++) {
    a[i] = temp[t];
    t++;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值