zoukankan      html  css  js  c++  java
  • 数组排序(5)- 归并排序

    (一)归并排序

        和选择排序一样,归并排序的性能不受输入数据的影响,但表现比选择排序好的多,因为始终都是O(n log n)的时间复杂度。代价是需要额外的内存空间。归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide andConquer)的一个非常典型的应用。归并排序是一种稳定的排序方法。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为2-路归并。

      1.算法描述

        (1)把长度为n的输入序列分成两个长度为n/2的子序列;

        (2)对这两个子序列分别采用归并排序;

        (3)将两个排序好的子序列合并成一个最终的排序序列。

      2.算法分析

      (1)最佳情况:T(n) = O(nlogn)

      (2)空间复杂度: O(n)

      (3)稳定性: 稳定

    (二)代码实现

    public class MergeSort {
        public static void main(String[] args) {
            int[] arr = {3,4,1,2,7,8,6,5,9};
            sort(arr);//排序
            System.out.println("-----------------------------------------");
            print(arr);//打印结果
        }
    
        public static void sort(int[] arr){
            if(arr == null || arr.length <= 1){
                return;
            }
            sort(arr,0,arr.length - 1);
        }
    
        private static void sort(int[] arr, int left, int right) {
            //边界条件
            if(left >= right){
                return;
            }
            int middle = (left + right) / 2;
            sort(arr,left,middle); //对左边序列进行排序
            sort(arr,middle + 1,right); //对右边序列进行排序
            //将两个子序列归并成一个有序序列
            merge(arr,left,middle,right);
            print(arr);
        }
    
        private static void merge(int[] arr, int left, int middle, int right) {
            //左边数组[left,middle],右边数组[middle + 1,right]
            int[] temp = new int[right - left + 1];
            int i = left;
            int j = middle + 1;
            int k = 0;
    
            while (i <= middle && j <= right){
                if(arr[i] <= arr[j]){//"="符号保证了归并排序是稳定排序
                    temp[k++] = arr[i++];
                }else {
                    temp[k++] = arr[j++];
                }
            }
            //左边数组没排序完
            while (i <= middle){
                temp[k++] = arr[i++];
            }
            //右边数组没排序完
            while (j <= right){
                temp[k++] = arr[j++];
            }
    
            //将temp数组赋值给原数组
            for (int p = 0; p < temp.length; p++) {
                arr[left + p] = temp[p];
            }
        }
    
        public static void print(int[] arr){
            StringBuilder sb = new StringBuilder("[");
            for (int i = 0; i < arr.length; i++) {
                sb.append(arr[i]);
                if(i != arr.length - 1){
                    sb.append(", ");
                }
            }
            System.out.println(sb.append("]"));
        }
    }
    MergeSort
  • 相关阅读:
    原生JS 碰撞检测
    sdw
    无题
    什么是递归?递归大讲义
    C#中常用的经典文件操作方法
    rpm包时遇到Header V3 DSA signature: NOKEY时解决办法
    Linux vim命令
    Linux yum命令详解
    visual studio 2013 快捷键大全
    D_S 线性表的顺序表示和实现
  • 原文地址:https://www.cnblogs.com/bug-baba/p/10548133.html
Copyright © 2011-2022 走看看