原理:

归并排序建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。

将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。

归并过程为:比较a[i]和a[j]的大小,若a[i]≤a[j],则将第一个有序表中的元素a[i]复制到r[k]中,并令i和k分别加上1;否则将第二个有序表中的元素a[j]复制到r[k]中,并令j和k分别加上1,如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到数组r中从下标k到下标t的单元。归并排序的算法我们通常用递归实现,先把待排序区间[s,t]以中点二分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间[s,t]。

归并操作(merge),也叫归并算法,指的是将两个顺序序列合并成一个顺序序列的方法。

如 设有数列{6,202,100,301,38,8,1}

初始状态:6,202,100,301,38,8,1

第一次归并后:{6,202},{100,301},{8,38},{1},比较次数:3;

第二次归并后:{6,100,202,301},{1,8,38},比较次数:4;

第三次归并后:{1,6,8,38,100,202,301},比较次数:4;

总的比较次数为:3+4+4=11,;

逆序数为14;

 package lsg.ap.merge;

 import java.util.Random;

 public class MergeSort
 {

     /**
      * 归并排序
      * 1.将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。
                      若将两个有序表合并成一个有序表,称为二路归并。
      * 2.比较a[i]和a[j]的大小,注意a[i]和a[j]分属于左右两侧已经排好序的两个数组。
                      若a[i]≤a[j],则将第一个有序表中的元素a[i]复制到r[k]中,
                       并令i和k分别加上1;否则将第二个有序表中的元素a[j]复制到r[k]中,并令j和k分别加上1,
                        如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到数组r中从
                        下标k到下标t的单元。归并排序的算法我们通常用递归实现,先把待排序区间[s,t]以中点二分,
                        接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的
                        区间[s,t]。
      * @param array
      */
     private static void sort(int[] array,int i,int j)
     {
         if(i<j)
         {
             int middle=(i+j)/2;
             //递归处理相关的合并事项
             sort(array,i,middle);
             sort(array,middle+1,j);
             merge(array,i,middle,j);
         }
     }
     /**
      * 合并相关的数组内容
      * 同时使合并后的数组仍然有序
      * @param array
      * @param i
      * @param middle
      * @param j
      *  4 5 6     9 10 11
      *
      */
     private static void merge(int[] array, int i, int middle, int j)
     {
         //创建一个临时数组用来存储合并后的数据
         int[] temp=new int[array.length];
         int m=i;
         int n=middle+1;
         int k=i;
         while(m<=middle&&n<=j)
         {
             if(array[m]<array[n])
                 temp[k++]=array[m++];
             else
                 temp[k++]=array[n++];
         }
         //处理剩余未合并的部分
         while(m<=middle)
         {
             temp[k++]=array[m++];
         }
         while(n<=j)
         {
             temp[k++]=array[n++];
         }
         //将临时数组中的内容存储到原数组中
         while(i<=j)
         {
             array[i]=temp[i++];
         }
     }
     public static void mergeSort(int[] data)
     {
         sort(data, 0, data.length - 1);
     }
     /**
      *
      * 输出相应数组的结果
      * @param array
      */
     private static void printArray(int[] array)
     {
        for(int value:array)
         System.out.print(" "+value+" ");
       System.out.println();
     }

     public static void main(String[] args)
     {
         //小数据量的测试
                 int[] array=new int[]{8,3,2,1,7,4,6,5};
                 //下面是大数据量的测试。这样才能看出不同算法的优劣
                 Random random=new Random();
                 int[] array2=new int[2000];
                 for(int j=0;j<2000;j++)
                 {
                     array2[j]=random.nextInt(100000);
                 }
           //输出原数组的内容
          System.out.println("排序前数组元素为:");
          printArray(array);
          long dateStart=System.nanoTime();
          //归并排序操作
          mergeSort(array);

          long dateEnd=  System.nanoTime();
          long totalTime=dateEnd-dateStart;
          System.out.println("归并排序的时间复杂度为:");
          System.out.println(totalTime+"纳秒");
         //输出排序后的相关结果
          System.out.println("排序后数组元素为:");
          printArray(array);
     }
 }

Java基础(48):归并排序的Java封装含原理,完整可运行,结合VisualGo网站更好理解)的更多相关文章

  1. Java基础(49):快速排序的Java封装(含原理,完整可运行,结合VisualGo网站更好理解)

    快速排序 对冒泡排序的一种改进,若初始记录序列按关键字有序或基本有序,蜕化为冒泡排序.使用的是递归原理,在所有同数量级O(n longn) 的排序方法中,其平均性能最好.就平均时间而言,是目前被认为最 ...

  2. Java基础-面向对象第一特性之封装(Encapsulation)

    Java基础-面向对象第一特性之封装(Encapsulation) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.理解什么是面向过程和面向对象 面向过程与面向对象都是我们编程中 ...

  3. Java基础系列1:Java基本类型与封装类型

    Java基础系列1:Java基本类型与封装类型 当初学习计算机的时候,教科书中对程序的定义是:程序=数据结构+算法,Java基础系列第一篇就聊聊Java中的数据类型. 本篇聊Java数据类型主要包括两 ...

  4. 【Java基础】11、java方法中只有值传递,没有引用传递

    public class Example { String testString = new String("good"); char[] testCharArray = {'a' ...

  5. 【Java基础】4、java中的内部类

    内部类的分类:常规内部类.静态内部类.私有内部类.局部内部类.匿名内部类. 实例1:常规内部类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 2 ...

  6. Java基础(十):封装

    在面向对象程式设计方法中,封装(英语:Encapsulation)是指一种将抽象性函式接口的实现细节部份包装.隐藏起来的方法.封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访 ...

  7. 夯实Java基础系列5:Java文件和Java包结构

    目录 Java中的包概念 包的作用 package 的目录结构 设置 CLASSPATH 系统变量 常用jar包 java软件包的类型 dt.jar rt.jar *.java文件的奥秘 *.Java ...

  8. java基础学习03(java基础程序设计)

    java基础程序设计 一.完成的目标 1. 掌握java中的数据类型划分 2. 8种基本数据类型的使用及数据类型转换 3. 位运算.运算符.表达式 4. 判断.循环语句的使用 5. break和con ...

  9. 夯实Java基础系列1:Java面向对象三大特性(基础篇)

    本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 [https://github.com/h2pl/Java-Tutorial](https: ...

随机推荐

  1. stage划分

    整个stage的划分会根据最后触发的action进行倒推,如果碰到宽依赖就将当前范围内的rdd划分为一个stage,直到所有的RDD遍历完为止.

  2. java RMI

    import java.rmi.*; public interface Hello extends Remote { public String getGreeting() throws Remote ...

  3. 【Android测试】【第一节】性能——CPU

    ◆版权声明:本文出自胖喵~的博客,转载必须注明出处. 转载请注明出处:http://www.cnblogs.com/by-dream/p/5065083.html 前言 本来打算写完全部的自动化测试之 ...

  4. const与#define宏常量 , inline与#define

    1.预处理 预处理器是在真正的编译开始之前由编译器调用的独立程序.预处理器可以删除注释.包含其他文件以及执行宏替代. 预处理命令(宏定义#define..#undef. 文件包含#include. 条 ...

  5. SQL Server中的Image数据类型的操作

    原文:SQL Server中的Image数据类型的操作 准备工作,在库Im_Test中建立一张表Im_Info,此表中有两个字段,分别为Pr_Id (INT),Pr_Info (IMAGE),用来存储 ...

  6. c#基础,面试前迅速巩固c#最基础知识点

    n年前为了面试,搜罗的C#基础知识,记在了文档里.今天写到博客园里,与人分享,因为不是专家,所以仅供参考. 1.面向对象 在面向对象概念提出之前,语言都是面向过程的,说到面向对象,应该与面向过程比较, ...

  7. android studio配置AndroidAnnotations

    现在很多人都使用Android studio开发工具代替eclipse了,当然的 在eclipse使用的好的一些开发框架也会对应的在android studio上面使用. 参考文档:http://bl ...

  8. JAVA并发编程的艺术

    CAS有两个特点: 1.for循环 2.compareAndSet(可能别的线程先改变然后又重置,此时CAS是成功的,也就是CAS执行的过程中,可能多个线程对此变量做了修改,而不是各个线程互斥的修改) ...

  9. http://www.cnblogs.com/littlemonk/p/5705476.html

    http://www.cnblogs.com/littlemonk/p/5705476.html

  10. 如何查看Servlet、JSP的版本(Tomcat V7.0.70)

    1. 简要说明:Tomcat6.0 所支持的是Servlet2.5,Tomcat 7.0 所支持的Servlet3.0,Servlet2.5 和Servlet3.0的差异较大,对于Servlet3.0 ...