• 排序算法(归并排序)


      关于排序算法,常见的大致有:冒泡排序、插入排序、选择排序、快速排序、归并排序、桶排序、计数排序等。每一种排序算法都有它们各自的优劣和适用场景。一般可以从这么几个角度来衡量排序算法:

      1.最好时间复杂度、最坏时间复杂度、平均时间复杂度

      2.是否是原地排序算法:原地排序算法,指空间复杂度为O(1)

      3.是否是稳定排序算法:稳定排序算法,指如果待排序序列中有值相等的元素,经过排序之后,值相等元素的顺序保持不变

      关于归并排序:

    #综述:
        1.冒泡排序、插入排序、选择排序算法的时间复杂度都是O(n^2)。只适合小规模数据的排序
        2.归并排序、快速排序算法的时间复杂度是O(nlogn)。适合大规模数据的排序
        3.归并排序、快速排序算法都应用了分治思想
        
    #描述归并排序:
        归并排序的核心思想,就是分而治之。比如要排序一个数组,先把数据从中间分成前后两个部分,然后对前后两部分分别排序,再将排好序的两部分进行合并。最终整个数组就排好序了。
        
    #实现公式:
        地推公式:
            merge_sort(p…r) = merge(merge_sort(p…q), merge_sort(q+1…r))
    
        终止条件:
            p >= r 不用再继续分解

      代码实现:

    package com.anan.algorithm;
    
    import java.util.Arrays;
    
    /**
     * 归并排序
     */
    public class MergeSort {
    
        public static void main(String[] args) {
            int[] a={4,5,6,3,2,1,8,9,12,11,8};
            System.out.println("排序前:"+ Arrays.toString(a));
    
            // 排序
            mergeSort(a,0,a.length-1);
    
            System.out.println("排序后:"+Arrays.toString(a));
        }
    
        // 第一步:拆分
        public static void mergeSort(int[] a,int left,int right){
            // 递归终止条件
            if(left>=right)return ;
    
            // 计算中间位置
            int mid = (left+right)/2;
            // 中间位置向左方向,左边继续拆分
            mergeSort(a,left,mid);
            // 中间位置向右方向,右边继续拆分
            mergeSort(a,mid+1,right);
    
            // 合并的过程
            merge(a,left,mid+1,right);
        }
    
        // 第二步:合并
        /**
         *  参数:
         *      a:数组
         *      left:指向数组第一个元素
         *      mid:指向数组分割元素
         *      right:指向数组最后一个元素
         */
        public static void merge(int[] a,int left,int mid,int right){
            // 左边数组大小
            int[] leftA = new int[mid-left];
            // 右边数组大小
            int[] rightA = new int[right-mid+1];
    
            // 左边数组填充数据
            for(int i=left;i<mid;i++){
                leftA[i-left]=a[i];
            }
    
            // 右边数组填充数据
            for(int j=mid;j<=right;j++){
                rightA[j-mid]=a[j];
            }
    
            // 定义两个位置指针
            int L_INDEX=0,R_INDEX=0;
            // a数组第一个元素位置
            int k=left;
    
            // 比较两个数组的值,将小的一个放入数组a中
            while(L_INDEX<leftA.length && R_INDEX<rightA.length){
                // 谁比较小,谁将元素放入大数组中,移动指针,继续比较下一个
                if(leftA[L_INDEX] < rightA[R_INDEX]){
                    a[k]=leftA[L_INDEX];
    
                    // 移动位置
                    L_INDEX++;
                    k++;
                }else{
                    a[k] = rightA[R_INDEX];
    
                    // 移动位置
                    R_INDEX++;
                    k++;
                }
    
            }
    
            // 如果左边的数组还没有比较完成。右边的数组已经比较完成。则将左边余下的数直接放入大数组a中
            while(L_INDEX<leftA.length){
                a[k] = leftA[L_INDEX];
    
                // 移动位置
                L_INDEX++;
                k++;
            }
    
            // 如果右边的数组还没有比较完成。左边的数组已经比较完成。则将右边余下的数直接放入大数组a中
            while(R_INDEX<rightA.length){
                a[k] = rightA[R_INDEX];
    
                // 移动位置
                R_INDEX++;
                k++;
            }
    
        }
    }

      

  • 相关阅读:
    SpringBoot应用配置常用相关视图解析器
    从Spring到SpringBoot构建WEB MVC核心配置详解
    集美大学网络15软工团队作业8分数统计
    集美大学网络15软工个人作业4分数统计
    集美大学网络15软工个人作业5分数统计
    集美大学网络15软工团队作业9分数统计
    Alpha冲刺阶段评分发布
    事后诸葛亮作业评分表
    软工网络15个人作业3-评分发布
    软工网络15个人阅读作业1-评分发布
  • 原文地址:https://www.cnblogs.com/itall/p/11137739.html
Copyright © 2020-2023  润新知