归并排序

归并排序:两个有序的数组合并成一个数组,指针I为第一个数组的开头,指针J为第二个数组的开头,比较两个元素,选择相对小的元素放入到合并空间,并移动指针到下一个

分成两个数组,两个数组都是有序的

在这里插入图片描述
比较大小2>1,1移到新数组里面,J指针往后一格
在这里插入图片描述
比较大小3>2,2移到新数组里面,I指针往后一格
在这里插入图片描述
比较大小4>3,3移到新数组里面,J指针往后一格
在这里插入图片描述
比较大小9>4,4移到新数组里面,I指针往后一格
在这里插入图片描述
比较大小9>5,5移到新数组里面
在这里插入图片描述
只剩下数字9,放上去
在这里插入图片描述
一般情况下,数组都不是有序的,因此程序一般有递归把数组分到最小,然后用上面两个有序数组合并到一个数组。
如:
在这里插入图片描述
现在从下往上,从每个小数组里排序合并数组排序(新数组)(从下往上看)
在这里插入图片描述

代码

假如两个数组是有序的
245 139

package com.my;

public class MergeSort {

    public static void main(String[] args) {
        int[] ints1= new int[]{2,4,5};
        int[] ints2= new int[]{1,3,9};

        //合并成新数组
        int[] newInts = new int[ints1.length+ints2.length];
        int i=0,j=0;
        int p=0;
        //第一想的,如图上第一第二张
        //比较大小2>1,1移到新数组里面,J指针往后一格
        if(ints1[i]>ints2[j]){
            newInts[p++]= ints2[0];
            j++;
        }else{
            newInts[p++]= ints1[0];
            i++;
        }
        print(newInts);
    }

    public static void print(int[] ints){
        for(int i:ints){
            System.out.print(i);
        }
    }
}

100000

2放上去,继续走

package com.my;

public class MergeSort {

    public static void main(String[] args) {
        int[] ints1= new int[]{2,4,5};
        int[] ints2= new int[]{1,3,9};

        //合并成新数组
        int[] newInts = new int[ints1.length+ints2.length];
        int i=0,j=0;
        int p=0;
        //第一想的,如图上第一第二张
        //比较大小2>1,1移到新数组里面,J指针往后一格
        if(ints1[i]>ints2[j]){
            newInts[p++]= ints2[0];
            j++;
        }else{
            newInts[p++]= ints1[0];
            i++;
        }

        //2放上去
        if(ints1[i]>ints2[j]){
            newInts[p++]= ints2[0];
            j++;
        }else{
            newInts[p++]= ints1[0];
            i++;
        }
        print(newInts);
    }

    public static void print(int[] ints){
        for(int i:ints){
            System.out.print(i);
        }
    }
}

120000

合并代码块

if(ints1[i]>ints2[j]){
            newInts[p++]= ints2[0];
            j++;
        }else{
            newInts[p++]= ints1[0];
            i++;
        }

合并后

package com.my;

public class MergeSort {

    public static void main(String[] args) {
        int[] ints1= new int[]{2,4,5};
        int[] ints2= new int[]{1,3,9};

        //合并成新数组
        int[] newInts = new int[ints1.length+ints2.length];
        int i=0,j=0;
        int p=0;
        //第一想的,如图上第一第二张
        //比较大小2>1,1移到新数组里面,J指针往后一格
        while(i<ints1.length && j<ints2.length){
            if(ints1[i]>ints2[j]){
                newInts[p++]= ints2[j];
                j++;
            }else{
                newInts[p++]= ints1[i];
                i++;
            }
        }
        print(newInts);

    }

    public static void print(int[] ints){
        for(int i:ints){
            System.out.print(i);
        }
    }

}

123450

修改判断值(临界值),或者添加

package com.my;

public class MergeSort {

    public static void main(String[] args) {
        int[] ints1= new int[]{2,4,5};
        int[] ints2= new int[]{1,3,9};

        //合并成新数组
        int[] newInts = new int[ints1.length+ints2.length];
        int i=0,j=0;
        int p=0;
        //第一想的,如图上第一第二张
        //比较大小2>1,1移到新数组里面,J指针往后一格
        while(i<ints1.length && j<ints2.length){
            if(ints1[i]>ints2[j]){
                newInts[p++]= ints2[j];
                j++;
            }else{
                newInts[p++]= ints1[i];
                i++;
            }
        }
        //添加最后值
        //添加最后值
        while(i<=ints1.length-1){
            newInts[i]=ints1[i];
            i++;
        }
        while(j<=ints2.length-1){
            newInts[p]=ints2[j];
            j++;
        }

        print(newInts);

    }

    public static void print(int[] ints){
        for(int i:ints){
            System.out.print(i);
        }
    }

}

123459

上面是两个有序数组的思维,一般情况下我们针对一个无序数组去排序,先展示下一个无序数组,分开后是有序的,
{1,4,7,8,3,6,9}分成两个后,代码上的指针也要对应的改
1278
369

package com.my;

public class MergeSort {

    public static void main(String[] args) {
        int[] ints1= new int[]{1,4,7,8,3,6,9};

        int[] merge = merge(ints1);
        print(merge);

    }


    private static int[] merge(int[] ints1) {
        int[] newInts = new int[ints1.length];
        int mid = newInts.length/2;
        int i=0,j=mid+1;
        int p=0;
        //第一想的,如图上第一第二张
        while(i<mid && j<ints1.length){
            if(ints1[i]>=ints1[j]){
                newInts[p++]= ints1[j];
                j++;
            }else{
                newInts[p++]= ints1[i];
                i++;
            }
        }
        //i指针往右剩下的
        while(i<=mid){
            newInts[p++]=ints1[i];
            i++;
        }
        //j指针往右剩下的
        while(j<=ints1.length-1){
            newInts[p]=ints1[j];
            j++;
        }
        return newInts;
    }

    public static void print(int[] ints){
        for(int i:ints){
            System.out.print(i);
        }
    }

}

1346789

代码优化 其实j++,i++可以写在判断里面

package com.my;

public class MergeSort {

    public static void main(String[] args) {
        int[] ints1= new int[]{1,4,7,8,3,6,9};

        int[] merge = merge(ints1);

        print(merge);

    }


    private static int[] merge(int[] ints1) {
        int[] newInts = new int[ints1.length];
        int mid = newInts.length/2;
        int i=0,j=mid+1;
        int p=0;
        //第一想的,如图上第一第二张
        while(i<mid && j<ints1.length){
            if(ints1[i]>=ints1[j]){
                newInts[p++]= ints1[j++];
            }else{
                newInts[p++]= ints1[i++];
            }
        }
        //添加最后值
        while(i<=mid){
            newInts[p++]=ints1[i++];
        }
        while(j<=ints1.length-1){
            newInts[p]=ints1[j++];
        }
        return newInts;
    }

    public static void print(int[] ints){
        for(int i:ints){
            System.out.print(i);
        }
    }

}

针对if else 只有两个判断条件时,改成三目运算符

package com.my;

public class MergeSort {

    public static void main(String[] args) {
        int[] ints1= new int[]{1,4,7,8,3,6,9};

        int[] merge = merge(ints1);

        print(merge);

    }


    private static int[] merge(int[] ints1) {
        int[] newInts = new int[ints1.length];
        int mid = newInts.length/2;
        int i=0,j=mid+1;
        int p=0;
        //第一想的,如图上第一第二张
        while(i<mid && j<ints1.length){
            newInts[p++]=ints1[i]>=ints1[j]?ints1[j++]:ints1[i++];
            /*if(ints1[i]>=ints1[j]){
                newInts[p++]= ints1[j++];
            }else{
                newInts[p++]= ints1[i++];
            }*/
        }
        //添加最后值
        while(i<=mid){
            newInts[p++]=ints1[i++];
        }
        while(j<=ints1.length-1){
            newInts[p]=ints1[j++];
        }
        return newInts;
    }

    public static void print(int[] ints){
        for(int i:ints){
            System.out.print(i);
        }
    }

}

因为要使用递归的排序,代码中merge并不灵活,因为最终往下分成一块一块,然后合并,所以merge这里缺少左指针,右指针,右边界
在这里插入图片描述

package com.my;

public class MergeSort {

    public static void main(String[] args) {
        int[] ints1= new int[]{1,4,7,8,3,6,9};
        int[] merge = merge(ints1,0,4,6);
        print(merge);

    }
    private static int[] merge(int[] ints1,int left,int right,int rightBorder) {
        //改变数值
        int[] newInts = new int[rightBorder-left+1];
        int mid = right;
        int i=left;
        int j=right;
        int p=0;

        while(i<=mid && j<rightBorder){
            newInts[p++]=ints1[i]>=ints1[j]?ints1[j++]:ints1[i++];
        }
        //添加最后值
        while(i<mid){
            newInts[p++]=ints1[i++];
        }
        while(j<=rightBorder){
            newInts[p]=ints1[j++];
        }
        return newInts;
    }

    public static void print(int[] ints){
        for(int i:ints){
            System.out.print(i);
        }
    }

}

最终代码

package com.my;

public class MergeSort {

    public static void main(String[] args) {
        int[] arrs= new int[]{1,4,7,8,3,6,9};
        sort(arrs,0,arrs.length-1);
        print(arrs);

    }

    private static void sort(int[] arrs,int L,int R) {
        //结束条件
        if(L==R)  return;
        //分成两半
        int mid = L+(R-L)/2;
        //左边排序,递归
        sort(arrs,L,mid);
        //右边排序,递归
        sort(arrs,mid+1,R);
        //合并
        merge(arrs,L,mid+1,R);
    }

    //假定排好序的情况下合并
    private static void merge(int[] arrs,int left,int right,int rightBorder) {
        //改变数值
        int[] newInts = new int[rightBorder-left+1];
        int mid = right-1;
        int i=left;
        int j=right;
        int p=0;

        while(i<=mid && j<=rightBorder){
            newInts[p++]=arrs[i]>arrs[j]?arrs[j++]:arrs[i++];
        }
        //添加最后值
        while(i<=mid){
            newInts[p++]=arrs[i++];
        }
        while(j<=rightBorder){
            newInts[p++]=arrs[j++];
        }
        //写回原先
        for(int m=0;m<newInts.length;m++) arrs[left+m] = newInts[m];
    }

    public static void print(int[] ints){
        for(int i:ints){
            System.out.print(i);
        }
    }
}

总结

要有递归的思想,而且要注意边界值

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值