交换排序-归并排序

返回目录

基本思想

归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法的一个非常典型的应用。将已有序的子
序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序
表,称为二路归并。——黑马程序员

自己的理解

将一个数组分为两个已经排序好的数组,然后按照顺序一一进行大小对比,然后将两个数组合并到一个数组中。。。(胡言乱语了)

动画演示

在这里插入图片描述
排序的活动就如同示例图所示这般。
每次都将数组分为左右两部分,先将左部分的数据排好顺序后再排右部分数据的顺序,两部分都拍好之后进行归并。
第一次分为左右部分数据时,左部分右是一个新的数组,右部分也是一个新的数组,再分别进行分左右部分的操作(所以需要使用递归)。
直到左右数组中都只有一个数据时递归结束(此时左右的数据都只有一个,那么一定是有序的)
因为有序,所以可以进行归并操作。
此时左边的数据已被归并完毕,然后再进行右边数据的归并操作,最后再进行左右的数据的归并操作,依次反复直到整个数组有序。

归并排序示例

package com.stu.algorithm.copy;

import java.util.Arrays;

/**
 * @version:
 * @author: 零乘一
 * @description: 类的简介
 * @date: 2021/9/29 22:37
 **/
public class Merge {
    public static int[] temp;
    public static void main(String[] args) {
        int a[] = {8,4,5,7,1,3,6,2};
        sort(a);
        System.out.println(Arrays.toString(a));
    }
    public static void sort(int[] a){
        //数组最左边的元素的下标
        int l = 0;
        //数组最右边的元素的下标
        int r = a.length - 1;
        //为临时存储的数组空间赋值
        temp = new int[a.length];
        sort(l,r,a);
    }

    public static void sort(int l, int r, int a[]){
        if (l>=r){//当左下标大于等于右下标时直接返回
            return ;
        }
        int mid = l + (r - l)/2;
        //对l到mid之间的元素进行排序
        sort(l,mid,a);
        //对mid到r之间的元素进行排序
        sort(mid+1,r,a);
        //进行两两归并
        merge(l,mid,r,a);
    }

    public static void merge(int l, int mid, int r, int a[]){
        //指向临时数组的下标
        int i = l;
        //指向左半边数组的下标
        int p1 = l;
        //指向右半边数组的下标
        int p2 =mid + 1;
        //当两边的数组都还没归并结束时持续循环
        while (p1 <= mid && p2 <= r){
            if (a[p1] < a[p2]){
                temp[i++] = a[p1++];
            }else {
                temp[i++] = a[p2++];
            }
        }
        //假设p1指向的这部分数组中的数据没有全部归并,将数组中的数据都填入临时的数组中
        while (p1<=mid){
            temp[i++] = a[p1++];
        }
        while (p2<=r){
            temp[i++] = a[p2++];
        }
        //将在临时数组中已经有序的数组写入正式的数组中
        for (int j = l; j <= r; j++) {
            a[j] = temp[j];
        }
    }

}
/*
测试数据:
        int a[] = {8,4,5,7,1,3,6,2};
        sort(a);
        System.out.println(Arrays.toString(a));
 */

代码解析

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
还需要这两个循环是因为在归并时,总会有一半数组中的所有元素首先进入临时的数组中,另一个数组中还有值没有进入数组中,但我我们并不清除是哪个数组中的数据没有完全写入临时数组中,所以要写两个判断,但是这两个循环只会执行一个循环

自己常出现的错误,在循环时总会忘记最后一个值(也就是循环条件是要等于最高位元素的下标)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值