Java基础(48):归并排序的Java封装含原理,完整可运行,结合VisualGo网站更好理解)
原理:
归并排序建立在归并操作上的一种有效的排序算法,该算法是采用分治法(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网站更好理解)的更多相关文章
- Java基础(49):快速排序的Java封装(含原理,完整可运行,结合VisualGo网站更好理解)
快速排序 对冒泡排序的一种改进,若初始记录序列按关键字有序或基本有序,蜕化为冒泡排序.使用的是递归原理,在所有同数量级O(n longn) 的排序方法中,其平均性能最好.就平均时间而言,是目前被认为最 ...
- Java基础-面向对象第一特性之封装(Encapsulation)
Java基础-面向对象第一特性之封装(Encapsulation) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.理解什么是面向过程和面向对象 面向过程与面向对象都是我们编程中 ...
- Java基础系列1:Java基本类型与封装类型
Java基础系列1:Java基本类型与封装类型 当初学习计算机的时候,教科书中对程序的定义是:程序=数据结构+算法,Java基础系列第一篇就聊聊Java中的数据类型. 本篇聊Java数据类型主要包括两 ...
- 【Java基础】11、java方法中只有值传递,没有引用传递
public class Example { String testString = new String("good"); char[] testCharArray = {'a' ...
- 【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 ...
- Java基础(十):封装
在面向对象程式设计方法中,封装(英语:Encapsulation)是指一种将抽象性函式接口的实现细节部份包装.隐藏起来的方法.封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访 ...
- 夯实Java基础系列5:Java文件和Java包结构
目录 Java中的包概念 包的作用 package 的目录结构 设置 CLASSPATH 系统变量 常用jar包 java软件包的类型 dt.jar rt.jar *.java文件的奥秘 *.Java ...
- java基础学习03(java基础程序设计)
java基础程序设计 一.完成的目标 1. 掌握java中的数据类型划分 2. 8种基本数据类型的使用及数据类型转换 3. 位运算.运算符.表达式 4. 判断.循环语句的使用 5. break和con ...
- 夯实Java基础系列1:Java面向对象三大特性(基础篇)
本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 [https://github.com/h2pl/Java-Tutorial](https: ...
随机推荐
- java event
What is an Event? Change in the state of an object is known as event i.e. event describes the change ...
- [have_fun] 好玩哒小游戏
好玩哒,打字小游戏:http://zty.pe/ 可好玩了,一起来玩吧!
- nRF51822之pstorage使用摘要
https://devzone.nordicsemi.com/question/15271/how-can-i-write-10kb-of-data-to-internal-flash/?answer ...
- Self和Super的用法
self 是类的隐藏的参数,指向当前当前调用方法的类,另一个隐藏参数是 _cmd,代表当前类方法的 selector.这里只关注这个 self.super 是个啥?super 并不是隐藏的参数,它只是 ...
- Apache的HBase与cdh的hue集成(不建议不同版本之间的集成)
1.修改hue的配置文件hue.ini [hbase] # Use full hostname with security. hbase_clusters=(Cluster|linux-hadoop3 ...
- 原因是未找到“sgen.exe”,或未安装 .NET Framework SDK v2.0
visual studio编译出现错误:错误 2 任务失败,原因是未找到“sgen.exe”,或未安装 .NET Framework SDK v2.0.该任务正在注册表项 HKEY_LOCAL_MAC ...
- php--validate表单验证
validate表单验证扩展规则 添加自定义检验(验证class) 获取html加入 class <input id="D_NUMBER" name="D_NUMB ...
- bodyParser注意“需要请求头的支持”
bodyParser 支持此类参数解析. 注意: 在提交之前需要指定http 请求头为 content-type=application/json 代码如下: var express = requir ...
- aspx后台页面添加服务器控件
System.Text.StringBuilder stringBuilder = new System.Text.StringBuilder(); System.IO.StringWriter st ...
- 20145211 《Java程序设计》第4周学习总结——园日涉以成趣
编程思想DRY和Once and Only Once DRY DRY原则的为"每一个知识都必须在系统内必须是单一的,明确的,权威的,具有代表性.当DRY的原则成功应用,在系统中,任何单一元素 ...