zoukankan      html  css  js  c++  java
  • 归并排序解析

    1 整体思路:

      归并排序的整体思想就是分而直至的思想,将整体数组进行二分 然后再进行合并,如下图:

     数组拷贝的过程,图解演示2967 -》2679 这个步骤

     2 代码解析

    package com.cxy.registersever.study;
    
    import java.util.Arrays;
    
    public class Sort {
        public static void main(String[] args) {
            int[]  a =new int[]{1,3,4,5,7,2};
            mergeSort(a);
            Arrays.stream(a).forEach(System.out::println);
    
        }
        public static void mergeSort(int[] a){
            int[] arr =new int[a.length]; // 创建零时数组  避免重复创建数组
            sort(a,0,a.length-1,arr);
        }
    
        private static void sort(int[] a, int left, int right, int[] arr) {
            if (left<right){
                int mid =(left+right)/2;
                sort(a,left,mid,arr); // 左边归并 
                sort(a,mid+1,right,arr); // 右边归并  为啥是mid+1   mid值已经进行了处理  所以对右边时候是mid+1
                merge(a,left,mid,right,arr); // 合并
            }
        }
    
        private static void merge(int[] a, int left, int mid, int right, int[] arr) {
            int i =left; // 左边的起始位置
            int j =mid +1; // 右边的起始位置
            int k =0; // 零时数组的索引位置
            while(i<=mid&&j<=right){  // 判断条件  left 的终值  不可以超过mid,mid+1 位置的值不可以超过right
                if (a[i]<=a[j]){
                    arr[k++] =a[i++]; // 将小的数据拷贝至零时数组  索引位置右移,零时数组位置也右移动
                }else{
                    arr[k++] =a[j++];// 将小的数据拷贝至零时数组 索引位置右移,零时数组位置也右移动
                }
            }
            while (i<=mid){ // 如果左边数据多,拷贝至数组最外边
                arr[k++] =a[i++];
            }
            while(j<= right){ // 如果右边数据多,拷贝至数组最外边
                arr[k++] =a[j++];
            }
            k =0; // 将零时数据组中的数据拷贝至原数组   零时数组中的数据会替代,所以不担心数组重复问题
            while(left<= right){  // 判断条件为啥left<= right  是循环终止条件,代表拷贝完毕
                a[left++] =arr[k++];
            }
        }
    }

     3  题解:

    给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。(leetcode4)

    处理方法1 :进行归并排序,然后找出中位数

    看代码如下:

    package com.cxy.registersever.study;
    
    import java.util.Arrays;
    
    public class Sort {
        public static void main(String[] args) {
            int[]  a =new int[]{1,3,4,10,7,2};
            int[]  b =new int[]{6,8,9};
            int[]  c =new int[a.length+b.length];
            for (int i =0;i<a.length+b.length;i++){  //9
                if (i<=a.length-1){
                    c[i] =a[i];
                }else{
                    c[i] =b[i-a.length];
                }
            }
    
            mergeSort(c);
            Arrays.stream(c).forEach(System.out::println);
            System.out.println(c[(a.length+b.length)/2]);
    
        }
        public static void mergeSort(int[] a){
            int[] arr =new int[a.length];
            sort(a,0,a.length-1,arr);
        }
    
        private static void sort(int[] a, int left, int right, int[] arr) {
            if (left<right){
                int mid =(left+right)/2;
                sort(a,left,mid,arr); // 左边归并
                sort(a,mid+1,right,arr); // 右边归并  为啥是mid+1   mid值已经进行了处理  所以对右边时候是mid+1
                merge(a,left,mid,right,arr); // 合并
            }
        }
    
        private static void merge(int[] a, int left, int mid, int right, int[] arr) {
            int i =left; // 左边的起始位置
            int j =mid +1; // 右边的起始位置
            int k =0; // 零时数组的索引位置
            while(i<=mid&&j<=right){  // 判断条件  left 的终值  不可以超过mid,mid+1 位置的值不可以超过right
                if (a[i]<=a[j]){
                    arr[k++] =a[i++]; // 将小的数据拷贝至零时数组  索引位置右移,零时数组位置也右移动
                }else{
                    arr[k++] =a[j++];// 将小的数据拷贝至零时数组 索引位置右移,零时数组位置也右移动
                }
            }
            while (i<=mid){ // 如果左边数据多,拷贝至数组最外边
                arr[k++] =a[i++];
            }
            while(j<= right){ // 如果右边数据多,拷贝至数组最外边
                arr[k++] =a[j++];
            }
            k =0; // 将零时数据组中的数据拷贝至原数组   零时数组中的数据会替代,所以不担心数组重复问题
            while(left<= right){  // 判断条件为啥left<= right  是循环终止条件,代表拷贝完毕
                a[left++] =arr[k++];
            }
        }
    }

    方法2  整个数组的中位数  说明需要循环m+n/2次就好了,因为两个数据是有序的

        public static int get(int[] a,int[] b){
            // 定义数组a下表位置  b数组下标位置   left接收上一个数,right接收下一个数据
            int i =0;
            int j =0;
            int left =-1;
            int right =-1;
            int mid =(a.length+b.length)/2;
            for (int k =0;k<= mid;k++){
                left =right;
                // 判断条件 i<=a.length   循环位置不可以超过数组
                // 当数组a的下标不超过a的值,a[i]<=b[j] 取数组a中的值,还要就是b数组没有值了 
                if (i<a.length&&(j>b.length||a[i]<=b[j])){
                    right =a[i++];
                }else{
                    right =b[j++];
                }
            }
            if ((a.length+b.length)%2 ==0){
                return right+left/2;
            }
            return right;
        }
  • 相关阅读:
    【Comet OJ Contest #15】孤独的吉姆 6
    【SSLOJ1467】U
    【SSLOJ1471】Y
    ajax调用webService
    泛型
    windows Server 2003 FTP
    ajax
    Linq 执行概念
    15款提高工作效率的工具分享
    Scrum是一种迭代式增量软件开发过程,通常用于敏捷软件开发
  • 原文地址:https://www.cnblogs.com/cxyxiaobao/p/15533729.html
Copyright © 2011-2022 走看看