归并排序用Java实现

归并排序

思想

把一个的数组给分成一级一级的小组 小组内部进行排序然后几个小组进行合并再排序
用尚硅谷韩顺平老师做的图这是尚硅谷韩顺平老师做的图
思想简而言之就是分而治之

代码实现

先把主函数给放上来

public static void main(String[] args) {
        int[] arr ={6,1,3};
        int []temp = new int[arr.length];
        mergeSort(arr,0,arr.length-1,temp);
        System.out.println(Arrays.toString(arr));
    }

这个mergeSort就是来实现归并排序的方法

数组成小组
public static void mergeSort(int[] arr, int left, int right, int[] temp){
 System.out.println("left是"+left+"  right是"+right);
 //可以通过这个来看递归里面的left和right
    if(left <right){
    int mind=(left+right)/2;
    mergeSort(arr,left,mind,temp);
    mergeSort(arr,mind+1,right,temp);
    }

上面的 if(left <right) 这个是很关键的
当递归到组里面只有一个数字的时候就需要退出递归了
因为你一个数字还拍啥顺序 比较数字大小起码得两个数字吧
如果只有一个数字的时候就会 left=right
老师给的图是数组有偶数个数字 那如果奇数个数分组会有一个多余的会咋办?

答案是奇数不参与最后一次分组

假如有三个数 123
第一次分组 123
第二次分组 12 和 3
到第三次分组 1 和 3(因为不满足left<right不进入if里面完成递归)

将分开的小组给合起来

这部分是最难的

这个步骤是
排序→合起来→再排序 →再合起来
直到完成

分完之后都会有左边部分和右边部分
两边分别有两个指针指着
选择两个指针指的最小的那个放到另一个数组里面
指针放完数字之后向后挪动
如果有一边已经放完了就无脑把另一半的也一个个放到另一个数组
等都放完之后把另一个数组里面排好顺序的数再放回原数组

这里再用一下尚硅谷韩顺平老师的图
在这里插入图片描述
在这里插入图片描述

首先是把左右两边的数字给按顺序放到另一个数组


    public static void merge(int[] arr, int left, int mind,int right, int[] temp){
    int l=left;
    int m=mind+1;
    int t=0;
    while(l<=mind&&m<=right){
        if(arr[l]<=arr[m]){
            temp[t]=arr[l];
            t++;
            l++;
        }
       else  {
            temp[t]=arr[m];
            t++;
            m++;
        }
    }
    //注意注意注意 这上面的是把一遍的放完
//==============================================
//注意注意注意 这下面的是当一遍放完之后
//把另一边给直接无脑放进去
while(l<=mind){
    temp[t]=arr[l];
    l++;
    t++;
}
while(m<=right){
    temp[t]=arr[m];
    m++;
    t++;
}
    }

我们来想一下为什么当一边放完之后另一边可以无脑放

答案是因为当执行到下面的while的时候一定都是有顺序的
因为递归肯定都是执行到底之后再向上返回
上面的那个递归 递归到俩数就行了
左边一个数 右边一个数
他俩一比较一放(指放到另一个数组
)再一拿回来不就有顺序了

下面是合并的代码

		int lf=left;
		int t1=0;
        System.out.println("left是"+lf+"  right是"+right);
    while(lf<=right){
       arr[lf] =temp[t1];
       lf++;
       t1++;
    }

这就是从另一个数组temp把排序完的数字拿回来

这里细说一下为什么temp的t1被定义为0

因为这个空间只是用于排序的
所以它空间里面的数字被覆盖也没事
假如说排序数组有四个数字 1 2 3 4
temp的四个空间放东西的情况如下
1 2
3 4
1 2 3 4

下面是排序合并总体代码

 public static void merge(int[] arr, int left, int mind,int right, int[] temp){
    int l=left;
    int m=mind+1;
    int t=0;
    while(l<=mind&&m<=right){
        if(arr[l]<=arr[m]){
            temp[t]=arr[l];
            t++;
            l++;
        }
       else  {
            temp[t]=arr[m];
            t++;
            m++;
        }
    }
		while(l<=mind){
    	temp[t]=arr[l];
    	l++;
    	t++;
	}
		while(m<=right){
    	temp[t]=arr[m];
    	m++;
    	t++;
	}


		int lf=left;
		int t1=0;
        System.out.println("left是"+lf+"  right是"+right);
    while(lf<=right){
       arr[lf] =temp[t1];
       lf++;
       t1++;
    }
    
    }

总体代码

import java.util.Arrays;

public class MergetSort {
    public static void main(String[] args) {
        int[] arr ={1,3,6};
        int []temp = new int[arr.length];
        mergeSort(arr,0,arr.length-1,temp);
        System.out.println(Arrays.toString(arr));
    }
    public static void mergeSort(int[] arr, int left, int right, int[] temp){
        System.out.println("left是"+left+"  right是"+right);
    if(left <right){
    int mind=(left+right)/2;
    mergeSort(arr,left,mind,temp);
    mergeSort(arr,mind+1,right,temp);
    merge(arr,left,mind,right, temp);

    }
    }


    public static void merge(int[] arr, int left, int mind,int right, int[] temp){
    int l=left;
    int m=mind+1;
    int t=0;
    while(l<=mind&&m<=right){
        if(arr[l]<=arr[m]){
            temp[t]=arr[l];
            t++;
            l++;
        }
       else  {
            temp[t]=arr[m];
            t++;
            m++;
        }
    }
		while(l<=mind){
		    temp[t]=arr[l];
		    l++;
		    t++;
		}
		while(m<=right){
   		 temp[t]=arr[m];
   		 m++;
	    t++;
		}


		int lf=left;
		int t1=0;
        System.out.println("left是"+lf+"  right是"+right);
   	 while(lf<=right){
       arr[lf] =temp[t1];
       lf++;
       t1++;
    	}
    	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值