常见算法之排序(进阶部分)_归并排序_02

中科院计算机算法设计与分析各章作业+历年习题 立即下载

----------------------------------------常见算法之排序(基础部分)_01-----------------------------------------------

进阶排序算法
排序时间复杂度空间复杂度
归并排序(Merge Sort)O(N*logN)O(N)
快速排序(Quick Sort)O(N*logN)O(logN)
堆排序(Heap Sort)O(N*logN)O(1)

 

用master method方法求递归程序的时间复杂度如下:

设T( n ) = a * T( n / b ) +  O( n ^ d )
若log a / log b > d 则T( n ) = O( n ^ ( log a / log b))
若log a / log b > d 
则T( n ) = O( n ^ d )
若log a / log b > d 

则T( n ) = O( N ^ d * log N )


调用Array.sort()函数对数组排序,其实用的是综合排序。当子数组的内容小于60时,直接用插入排序,因为插入排序的时间复杂度的常数项小,当n小时优势就体现出来了。当子数组的内容大于60时,会调用归并排序或者快速排序。当数组的内容为基础类型时,会调用快速排序,快速排序里面的partition过程会将数组分成子数组,然后继续判断是否大于60;当数组的内容为类类型时(包括自定义类),调用归并排序,归并排序中每次递归都会将数组分为子数组,然后继续判断是否大于60。采用综合排序的原因是考虑稳定性,基础类型不用考虑稳定性,所以用快速排序 (比如整型,一堆数字3是一样的)。

------------------------------------------------------归并排序--------------------------------------------------

public class Code_01_Sort 
{
	public static void main(String[] args) 
	{
		//初始化数组
		int len = (int)(Math.random()*20);//随机生成20以内的数组长度
		int[] arr = new int[len];
		for(int i = 0; i < len; i++)//在数组内随机生成1000内的值
		{
			arr[i] = (int)(Math.random()*1000) - (int)(Math.random()*1000);
		}
	
		mergeSort(arr);//调用归并排序
		
		for(int i = 0; i < len; i++)//格式化输出数组
			System.out.printf("%02d:%-+4d\n",i,arr[i]);

	}
	
	
	public static void mergeSort(int[] arr)
	{//这个函数主要用来统一函数接口,sortProcess才是归并排序
		System.out.println("归并排序:");
		if(arr == null)
			return;
		sortProcess(arr,0,arr.length-1);
	}
	
	public static void sortProcess(int[] arr, int L, int R)
	{//归并排序:用递归思想处理排序问题,归并指的是先递归,再合并
		if(L == R)//基础条件:如果子数组只有一个元素,就不再继续递归。
			return;
		int mid = L + ((R-L)/2);//中点位置,直接用(L+R)/2可能会溢出
		sortProcess(arr,0,mid);//递归的排序数组的左半部分
		sortProcess(arr,mid+1,R);//递归的排序数组的右半部分
		merge(arr,L,mid,R);//调用合并函数,将有序的左半部分和有序的右半部分排成总体有序
	}
	
	public static void merge(int[] arr, int l, int mid, int r)//L,mid,R分别指数组的开始位置,中间位置,结束位置
	{//合并函数
		int[] help = new int[r-l+1];//辅助数组
		int ptr_h = 0;//指针pointer_help,指向help数组
		int ptr_l = l;//指针pointer_left,指向左半部分数组
		int ptr_r = mid+1;//指针pointer_right,指向右半部分数组
		
		while(ptr_l <= mid && ptr_r <= r)//只要两边还有元素没比完,就一直比下去,直到其中一边元素都执行过对比的动作。
		{
			if(arr[ptr_l] < arr[ptr_r])//比较左边的有序数组和右边的游戏数组
			{
				help[ptr_h] = arr[ptr_l];//哪边的最小值小,就把该边最小值赋给help辅助数组,
				ptr_l++;//并把最小值小的那边的指针向右移一位
			}
			else
			{
				help[ptr_h] = arr[ptr_r];
				ptr_r++;
			}
			ptr_h++;//将help数组的指针向右移动一位
		}
		
		while(ptr_l <= mid)//左边元素还没对比完,则把左边的剩余元素直接填到help辅助数组去
		{
			help[ptr_h] = arr[ptr_l];
			ptr_h++;
			ptr_l++;
		}
		while(ptr_r <= r)//右边元素还没对比完,则把右边的剩余元素直接填到help辅助数组去
		{
			help[ptr_h] = arr[ptr_r];
			ptr_h++;
			ptr_r++;
		}
		
		for(int i = 0; i < help.length; i++)//将已排好序的辅助数组复制给元数组
		{
			arr[l+i] = help[i];
		}
	}
}


练习:求小和问题

//求小和问题:给定一个数字数组,将每个数左边比它小的数的值都累加起来,最终和是多少?
//思路:某个数的左边部分其实有无序都不影响该数的小和。可以用归并排序,边排序边求小和。
//在合并过程中返回给已排好序的两个区间进行整体排序时产生的小和。
//直接看代码会好懂一些,其实就是稍微改动了下归并排序。
public class Code01_ZuiXiaoHe 
{
	public static void main(String[] args)
	{
		int[] arr = {4,1,3,5,0,6};
		int result = smallSum(arr);
		System.out.println(result);
	}
	
	public static int smallSum(int[] arr)
	{
		if(arr == null || arr.length < 2)
			return 0;
		return mergeSort(arr, 0, arr.length-1);
	}
	
	public static int mergeSort(int[] arr, int l, int r)
	{
		if(l == r)
			return 0;
		int mid = (l +(r-l)/2);
		return mergeSort(arr, l ,mid) + mergeSort(arr,mid+1,r) + merge(arr,l,mid,r);
	}
	
	public static int merge(int[] arr, int l, int m, int r)
	{
		int[] help = new int[r-l+1];
		int point_h  = 0;
		int point_l = l;
		int point_r = m+1;
		int result = 0;
		
		while(point_l <= m && point_r <= r)
		{
			if(arr[point_l] < arr[point_r])
			{
				result += arr[point_l]*(r - point_r + 1);//有所改动的部分(某个数*右边比它大的个数)
				help[point_h] = arr[point_l];
				point_l++;
			}
			else
			{
				result += 0;
				help[point_h] = arr[point_r];
				point_r++;
			}
			point_h++;
		}
		
		while(point_l <= m)
		{
			help[point_h] = arr[point_l];
			point_h++;
			point_l++;
		}
		
		while(point_r <= m)
		{
			help[point_h] = arr[point_r];
			point_h++;
			point_r++;
		}
		
		for(int i = 0; i < help.length; i++)
		{
			arr[l+i] = help[i];
		}
		return result;
	}
}


FFmpeg魔改指南:让RTMP协议完美兼容H265的三种方法(含SRS适配技巧) 本文详细介绍了三种让RTMP协议兼容H265编码的FFmpeg魔改方案,包括基于官方补丁的标准改造、Intel的SVT-HEVC集成方案以及金山云的自定义扩展方案。文章重点解析了各方案的实现原理与适配技巧,并提供了在SRS 6.0服务器上进行深度配置和性能调优的完整实战指南,帮助开发者解决H265推流至传统RTMP服务器的兼容性问题。 阅读详情

相关推荐

超级详细!!!新手使用AutoDL跑深度学习(MixVPR项目)的学习记录

新手第一次在AutoDL上跑深度学习的实验,遇到一些问题,简单记录一下。如果大家发现问题,欢迎和我讨论。

weixin_45152283的博客 5万+

进阶排序算法

一、希尔排序: (可以看做插入排序的升级,属于插入排序类) 基本思想: 将待排序列划分为若干组,在每一组内进行插入排序,以使整个序列基本有序,然后再对整个序列进行插入排序。 基本有序的概念:就是小的关键字基本在前面,大的基本在后面,不大不小的基本在中间。 基本有序举例:{ 2,1,3, 6,4,7, 5,8,9 } 划分为若干组的目的:减少待排序记录的个数,并使整个

kindlyde 1487

黑金AXU9EG开发板深度学习部署全流程解析

本文详细解析了黑金AXU9EG开发板的深度学习模型部署全流程,从环境搭建、模型转换到上板验证,提供了实用的技术指导和优化技巧。该开发板基于Xilinx Zynq UltraScale+ MPSoC架构,特别适合边缘计算场景,通过FPGA加速实现高效AI推理。

weixin_29062613的博客 447

算法学习之--进阶排序算法(时间复杂度O(nlogn))

1.归并排序 基本思想:不断的将数据进行二分(逻辑上的二分,即将数组元素索引分块,并不是真的把数组内存进行二分),当二分到只有一个数组元素时开始归并,数组的每一个元素由其二分后数组的两个元素进行比较确定: 首先进行二分: 二分到第三层数组中仅有一个元素(即数组有序),然后开始向上进行归并:第二层左边的数组 [ 0 ] 位置元素由其二分后数组元素比较得出,显然应该是3,那么 [ 1 ]位置就是6,同理第二层右边数组归并后是1,4。再次向上归并,第一层数组[0]位置由其二分数组【3,6】【1,4..

j_oop的博客 995

QT编程之PCM音频播放与采集

Qt5/Qt6通用方案。

深之JohnChen的专栏 1170

软考高级,信息系统项目管理师(高项)经验分享

软考高级,信息系统项目管理师(高项)经验分享 2020-12-21信息系统项目管理师(俗称高项)成绩出来了54,55,47,终于成为高级工程师了。 本文以编写整体管理论文的格式进行,将分为项目启动、项目计划、项目执行、项目检查、项目收尾5个过程回顾高项的考试历程,希望对其他同学有借鉴意义。个人觉得可能对于一次考不过的人参考价值比较大。 第一阶段、项目启动阶段Start——决定考哪个科目。 如图,高级资格的类型有:信息系统项目管理师、系统分析师、系统架构设计师、......

zcheva的专栏 5万+

复杂性分析初步

复杂性概念   空间复杂度:指令空间、数据空间和环境栈空间(递归)   时间复杂度:由关键操作计数决定,一般将加减乘除和比较操作看作是基本操作(约定每个基本操作所用时间都是一个单位),然后确定程序总的执行步数(不能用机器的真正运行时间作衡量标准,因为影响运行时间的因素太多,甚至还有很多未知因素)。 复杂性举例 //寻找a[0:n-1]中的最大元素 template&amp;amp;amp;lt;class T&amp;amp;amp;gt; ...

qq_33740820的博客 3664

FPGA实战:手把手教你实现雷达信号数字下变频(DDC)完整流程

本文提供了一份完整的FPGA实现雷达信号数字下变频(DDC)的实战指南。内容涵盖从Matlab行为级仿真到FPGA硬件实现的完整闭环流程,详细讲解了数字混频、滤波、抽取等核心步骤,并分享了基于Vivado的IP核配置、数据位宽量化及资源优化等关键工程实践经验,旨在帮助读者掌握DDC系统的硬件实现与调试。

dog123的博客 342

算法分析与设计期末总结(1)

第一章 算法引论 1、 如果存在正的常数和自然数N0,使得当N>= N0时有f(N) (1) O(f) + O(g) = O(max(f, g)) (2) O(f) + O(g) = O(f + g) (3) O(f)O(g) = O(fg) (4) 如果g(N) = O(f(N)),则O(f) + O(g) = O(f) (5) O(Cf(N)) = O(f(N)),其中C是一个正的

liujing_555的博客 1万+

Altium Designer20 PCB板子绘制

版层 top layer 顶层 bottom layer 底层 设置板子大小 布局 过孔 top layer层连到bottom layer层。通过via连接。 设置线宽 在design rules里可以设置线宽。 右键new rule 可以新增线宽,电源设置成20mil 还可以设置很多其他的线宽 修改安全距离 安全距离太短容易出现毛刺,然后短路,一般设置成20mil 修改元器件旋转角度 修改rotation step,每次旋转45°。 修改光标大小 下面的cursor type是修改光标

及时总结 2582

set_input_delay/set_output_delay介绍

针对这一类的情况,在做block时,cts之后,便需要将update_io_latency给关闭。那么,计算的timing就是错误的了。对于hier flow来讲,切分block,进行timing budget的时候,clock tree还未长。计算block端口上的timing,通常需要用到set_input_delay和set_output_delay告知工具外部电路的延迟信息,以方便工具计算端口上的timing。此时,工具在计算in2reg的timing时,便会将2.67ns的delay带进来。

芯冰乐 319

算法时间复杂度渐进阶排序_Python算法中的时间复杂度

在实现算法的时候,通常会从两方面考虑算法的复杂度,即时间复杂度和空间复杂度。顾名思义,时间复杂度用于度量算法的计算工作量,空间复杂度用于度量算法占用的内存空间。本文将从时间复杂度的概念出发,结合实际代码示例分析算法的时间复杂度。渐进时间复杂度时间复杂度是算法运算所消耗的时间,因为不同大小的输入数据,算法处理所要消耗的时间是不同的,因此评估一个算运行时间是比较困难的,所以通常关注的是时间频度,即算法...

weixin_42515377的博客 2269

3D高斯压缩黑科技开源!1GB场景压到42MB,Web3D迎来“WebP时刻”——SOG格式深度解析

Web3D迎来革命性突破!PlayCanvas开源全新3D高斯泼溅压缩格式SOG,将1GB场景压缩至仅42MB,体积缩小95%,加载速度提升10倍+。SOG通过将3D数据编码为WebP纹理+元数据,实现GPU零拷贝实时渲染,完美兼容WebGL/WebGPU。实测显示,4百万高斯点的场景在手机上1.5秒内完成加载,内存占用降低83%。这一技术突破为电商展示、虚拟旅游、工业设计等领域带来新机遇,开发者可通过开源工具链快速集成。SOG被誉为"3D界的WebP",有望成为下一代3D互联网的基础设

这里汇聚了前沿的技术分享与实用的开发技巧,带你探索从创意到企业的技术创业之路。 865

归并排序C++算法实现

定义:归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。 简单的来说,归并排序主要分为三步,一是对数组的划分,二是对数组的排序,三是对数组的合并。划分的大小是可以随自...

Eggy个蛋 2万+

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

排序算法之归并排序

归并排序和选择排序一样,归并排序的性能不受输入数据的影响,但表现比选择排序好的多,因为始终都是O(n log n)的时间复杂度。代价是需要额外的内存空间。

9288

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

归并排序算法

一文速学归并排序

chenchenchencl的博客 7677

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

【初阶数据结构】常见五大排序算法及部分算法优化讨论

本文全面介绍了排序的概念、常见排序算法的实现、复杂度及稳定性分析、选择题练习以及外排序之文件归并排序实现。排序可分为内部排序和外部排序,常见的内部排序算法有插入排序、希尔排序、选择排序、堆排序、冒泡排序、快速排序、归并排序、计数排序等。每种算法都详细阐述了其基本思想、实现步骤、算法复杂度、特性总结等内容。还分析了排序算法的稳定性,并通过选择题练习加深理解。最后介绍了外排序的概念和文件归并排序的实现方法,包括创建随机数据文件、思路分析和代码实现。

2401_82610555的博客 1453

【排序算法】归并排序与快速排序

一篇文章教你彻底理解快速排序和归并排序

Lin5200000的博客 2070

常见的排序算法

排序算法可谓数据结构模块中的重中之重,常见的哈希表,二叉树,搜索树/平衡树,位图等数据结构只是处理实际问题的抽象方法,实际在处理接受或生成的数据集时,排序算法显得尤其重要,排序算法家族很庞大,其中包括了冒泡排序,选择排序,插入排序,堆排序,快速排序,归并排序,基数排序,计数排序,希尔排序,箱排序,树型排序等众多算法,每种排序都有各自的特性,没有好坏之分,只有在特定的场景使用合适的排序算法才是上策,单纯的来比显得太过绝对,没有可比性。因为实际需求及各方面条件的限制使得排序算法的可选范围往往只缩小到某一种或某几

Xiao__Tian__的博客 9912

归并排序-自底向上的归并排序算法

归并排序 归并排序(Merge Sort)是建立在归并操作上的一种有效,稳定的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。 算法描述 分解: 将原序列分解成length长度的若干子序列 求解子问题: 将相邻的两个子序列调用Merge算法合并成一个有序子序列 合并: 由于整个序列存放在数字a中,排序过程是就地进行的,合并步骤不需要执行

qq_45727976的博客 2990

归并排序算法思想

归并排序算法思想: 分而治之(divide - conquer);每个递归过程涉及三个步骤 第一, 分解: 把待排序的 n 个元素的序列分解成两个子序列, 每个子序列包括 n/2 个元素. 第二, 治理: 对每个子序列分别调用归并排序MergeSort, 进行递归操作 第三, 合并: 合并两个排好序的子序列,生成排序结果. import java.util.Arrays;     

snailelf的专栏 1万+

[算法沉淀记录] 排序算法 —— 归并排序

归并排序是一种分治算法,由约翰·冯·诺伊曼在1945年发明。它的工作原理是将未排序的列表划分为n个子列表,每个子列表包含一个元素(包含一个元素的列表被认为是有序的),然后重复合并子列表以生成新的有序子列表,直到只剩下一个子列表。 归并排序是一种高效的排序算法,其优缺点如下:总体而言,归并排序是一种高效的通用排序算法,特别适合需要稳定排序和大量数据的情况。然而,如果内存使用是一个关键因素,或者数据集非常小,可能需要考虑其他排序算法。归并排序是一种高效的通用排序算法,由于其稳定性和(O(n log n))的时间

莫寒技术人生 1640

常见排序算法原理及实现——第二部分(归并排序、快速排序、堆排序)

常见排序算法原理及实现——第二部分(归并排序、快速排序、堆排序)

weixin_46935110的博客 1190

【算法】之归并排序

太阳风暴 彗星袭月,白虹贯日,仓鹰击于殿上。

qq_41346335的博客 6229

C++排序算法之归并排序

归并排序 (1)算法介绍      归并排序是建立在归并操作上的一种有效的排序算法。该算法是采用分治法的一个非常典型的应用,归并排序将两个已经有序的序列合并成一个有序的序列。      思路:假设我们有一个没有排好序的序列,那么我们首先使用分割的方法将这个序列分割成一个个已经排好序的子序列(当一个序列只有一个元素时,该序列自然是有序的)。然后再利用归并的方法将一个个有序的子序列合并成

YF_Li123的博客 1万+
上一篇: 常见算法之排序(基础部分)_冒泡+选择+插入排序_01
下一篇: 正确的理解二进制的原码、反码、补码运算_01
coder__666
博客等级 码龄9年 42粉丝 52原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值