java中归并排序和Master公式详解
作者:吃鱼的宗介 发布时间:2022-03-30 08:53:19
标签:java,归并排序,Master公式
基本思想
归并排序采取分治的思想进行排序,借用一张图片说明一下
将n个元素从中间切开,分成两部分。(左边可能比右边多1个数) 将步骤1分成的两部分,再分别进行递归分解。直到所有部分的元素个数都为1。 从最底层开始逐步合并两个排好序的数列。
优点在于,分治之后,合并排序的过程时间复杂度是O(N)(只需要扫描一遍就可以将两个有序的数组合并成一个有序数组)
实现
public static void MergeSort(int[] arr,int l , int r) {
if (l == r || r < 0){
return;
}
int middle = l+(r-l)/2; //取中值,可以防止达到Integer.MaxValue 溢出
MergeSort(arr,l,middle);
MergeSort(arr,middle+1,r);
sort(arr,l,middle,r);
}
/**
*
* @param arr 等待排序的数组
* @param l 左数组第一个指针
* @param middle 分割左右数组
* @param r 右数组最后一个指针
*/
private static void sort(int[] arr, int l, int middle, int r) {
int[] temp = new int[arr.length];
System.arraycopy(arr, 0, temp, 0, arr.length);
int right_first = middle+1;
int tempIndex = l;
while (l <= middle && right_first <= r){
if (temp[tempIndex] < temp[right_first]){
arr[l++] = temp[tempIndex++];
}else {
arr[l++] = temp[right_first++];
}
}
while (tempIndex <= middle){
arr[l++] = temp[tempIndex++];
}
while (right_first <= r ){
arr[l++] = temp[right_first++];
}
}
对数器验证
我们可以写个对数器,使用暴力排序的方式验证我们的排序方法是否准确
//生成1-100内随机数组
public static int[] getParamArrays(){
int[] result = new int[(int) (Math.random() * 100)];
//随机生成数
for (int i = 0; i < result.length; i++) {
result[i] = (int) (Math.random() * 100);
}
return result;
}
public static void main(String[] args){
for (int i = 0; i < 1000000; i++) {
int[] nums = getParamArrays();
int[] temp = nums;
MergeSort(nums,0,nums.length-1);
Arrays.sort(temp);
//通过自定义比较次数,对随机数组进行排序验证正确性
if (!nums.equals(temp)){
System.out.println("wrong");
}
}
System.out.println("end");
}
递归时间复杂度计算 Master 公式
形如
T(N) = a * T(N/b) + O(N^d)(其中的a、b、d都是常数)
的递归函数,可以直接通过Master公式来确定时间复杂度
如果 log(b,a) < d,复杂度为O(N^d)
如果 log(b,a) > d,复杂度为O(N^log(b,a))
如果 log(b,a) == d,复杂度为O(N^d * logN)
此公式适用于子递归规模相等的情况下
a表示递归的次数也就是生成的子问题数,b表示每次递归是原来的1/b之一个规模,O(N^d) 表示分解和合并所要花费的时间之和(除开递归的复杂度)
此处就是 T(N)= 2*T(N/2)+O(N^1) 适用于第三种情况 复杂度为 O(nlogn)
来源:https://blog.csdn.net/qq_38895905/article/details/122337305


猜你喜欢
- 介绍在进行项目开发的时候,刚好需要用到对字符串表达式进行求值的处理场景,因此寻找了几个符合要求的第三方组件LambdaParser、Dyna
- 1)如何获得MediaPlayer实例:可以使用直接new的方式:MediaPlayer mp = new MediaPlayer();也可
- 一、使用@Profile1.1、@Profile修饰类开发环境package com.example.demo.config;import
- 开发人员可以用以下两种方式声明UI:一是通过.xml文件(不带预览界面)或者.axml文件(带预览界面)来描述;二是用C#代码实现。&nbs
- 注解类@Documented@Target({ElementType.METHOD})@Retention(RetentionPolicy.
- C#文件夹加锁小工具用C#语言实现一个文件夹锁的程序,网上类似的“xxx文件夹xxx”软件很多,但是基本上都是C/C++语言实现的,且都没有
- Jetty是一个轻量级的高度可扩展的基于 java的web服务器和servlet引擎。下面是 使用 Intellij IDEA 的maven
- Android5.0之后提供了JobService和JobScheduler,用于在稍后的某个时间点或者当满足某个特定的条件时执行一个任务
- 前言目前互联网公司,大部分项目都是基于分布式,一个项目被拆分成几个小项目,这些小项目会分别部署在不同的计算机上面,这个叫做微服务。当一台计算
- 最近有一个java实验,要求用java使用数据库,于是本人新手小白,在idea上卡了好半天希望看到这个博客的人能解决问题,跳过一些坑首先,我
- Activity是最基本的模块,一般称之为"活动",在应用程序中,一个Activity通常就是一个单独的屏幕。简单理解,
- 最近一直在调用微信的API,却发现一直调用不成功,纠结了好久,各方面找教程,找官方,官方里的文档也只是写得很模糊,说是按三步走。1、申请Ap
- 一、Activity的生命周期首先,我们来了解一下Activity典型的生命周期一个Activity从启动到结束会以如下顺序经历整个生命周期
- Kotlin中的一个伟大创前举就是空指针的处理,在代码的编译阶段就能检测可能出现的空指针问题,示例代码如下:data class Perso
- 用法在java中经常会遇到需要对数据进行类型转换的场景,String类型的数据转为Int类型属于比较常见的场景,主要有两种转换方法:1. 使
- Http通信概述Http通信主要有两种方式POST方式和GET方式。前者通过Http消息实体发送数据给服务器,安全性高,数据传输大小没有限制
- 先看看常规的隐藏状态栏的方法:方法一:@Overrideprotected void onCreate(Bundle savedInstan
- C++类返回值是*this成员函数当C++类的成员函数其返回值是*this时,表示返回值是调用该成员函数的变量的引用。例如:class A{
- 我们知道,Java和MySQL中的数据类型是不同的,Java中除了基本数据类型,还有对象。有时候使用MySQL存储数据,或者从MySQL中读
- 二分查找算法的思想很简单,《编程珠玑》中的描述: 在一个包含t的数组内,二分查找通过对范围的跟综来解决问题。开始时,范围就是整个