《算法导论的Java实现》 1_3.1 分治算法

算法导论——24.1 BellmanFord算法java实现 Bellman - ford算法是求含负权图的单源最短路径算法,效率很低,但代码很容易写。其原理为持续地进行松弛(原文是这么写的,为什么要叫松弛,争议很大),在每次松弛时把每条边都更新一下,若在n-1次松弛后还能更新,则说明图中有负环,因此无法得出结果,否则就完成。Bellman - ford算法有一个小优化:每次松弛先设一个标识flag,初值为FALSE,若有边更新则赋值为TRUE,最终如果还是FALSE则直接成功退出。Bellman-ford算法浪费了许多时间去做没有必要的松弛,而SPFA算法用队列进行 阅读详情

第一章 算法概念
1.3 算法设计
1.3.1 分治算法

伪代码:
MERGE(A, p, q, r)
 1  n1 ← q - p + 1
 2  n2 ← r - q
 3  create arrays L[1 ‥ n1 + 1] and R[1 ‥ n2 + 1]
 4  for i ← 1 to n1
 5       do L[i] ← A[p + i - 1]
 6  for j ← 1 to n2
 7       do R[j] ← A[q + j]
 8  L[n1 + 1] ← ∞
 9  R[n2 + 1] ← ∞
10  i ← 1
11  j ← 1
12  for k ← p to r
13       do if L[i] ≤ R[j]
14             then A[k] ← L[i]
15                  i ← i + 1
16             else A[k] ← R[j]
17                  j ← j + 1

这个函数的功能是,将A[p … r]排顺序,假设A[p … q]和A[q + 1 … r]已经排好顺序(p≤q<r—)。
我手上的影印本《算法导论》里,≤和<很难区分清楚,所以不知道是否中文版本身就有问题,看上去都一样。但实际上,这种边界条件非常重要的,所以,必须参照英文原版。

显然,这只是分治算法的一部分。大方向上来说,分治算法一般分为:分治,解决,合并。
上面的MERGE(A, p, q, r)就是“合并”。

而这段分治排序法的合并部分,在其他场合也一样有用。那就是对已经排序的数列进行合并。由于没有双重循环,所以其时间复杂度为Θ(n) 。循环体最多被执行n次(n = r - p + 1)。

伪代码:
MERGE-SORT(A, p, r)
1 if p < r
2   then q ← ┕(p + r)/2┙
3        MERGE-SORT(A, p, q)
4        MERGE-SORT(A, q + 1, r)
5        MERGE(A, p, q, r)

这就是“分治”和“解决”了。递归的好处,或者说这里的分治的好处就是:程序清晰。上面这段代码太让人赏心悦目了。q ← ┕(p + r)/2┙,设定分治点;A[p … r]分成A[p … q]和A[q + 1 … r]两部分,然后调用MERGE(A, p, q, r)进行“合并”。

Java实现:



输出:
merge method test
1 2 4 4 6 7 8 10 11 14 17 20 30 40
mergeSort method test
1 2 2 3 4 5 6 6

coding后感
1,很有意思的是,java.util.Collections的“public static <T> void sort(List<T> list, Comparator<? super T> c)”,里面调用的java.util.Arrays类里面的函数,正是“private static void mergeSort(Object[] src, Object[] dest, int low, int high, int off)”,这是个private函数,外面不可见,参数low,high,off和《算法导论》里的参数p,q,r,意思是不同的,特别是off是偏移量,而q是中间值;《算法导论》里面的MERGE(A, p, q, r)是只是合并,分治和解决在MERGE-SORT(A, p, r)里面,而Arrays是放在的mergeSort里面,全部搞定的。这点区别还是要注意一下的。
2,为了练手,看到Arrays里面有mergeSort后,故意不参考它,只是根据《算法导论》的伪代码写下的程序,结果当然是差不多。 看来我一个人也抵得上Josh Bloch、Neal Gafter、John Rose他们仨了(Arrays类的作者,2006年),呵呵。
3,上一篇写“插入排序”的时候,我说“插入排序本身是没有任何实用价值的”。可能是我错了。因为Arrays里面也有插入排序,上次我没有看到。看来插入排序也是有实用的地方,就现在这个分治排序也是有用到的地方的,凡排序必云“快速排序”,是不行的。
4,合并函数merge,其实还是很有用的。不只是这个分治算法里可用,更普遍的情况,对2个(甚至多个)有序组数的再排序,可以把两个已排好序的数组,直接连在一起后,调用merge。所以我特地加了段测试merge函数的代码放在main的最前面。
5,Java的数组从0开始是到“长度-1”为止这个特点,再次使我比较困扰。比方说mergeSort里面的if文,伪代码的是“ p < r”,如果Java里面也写“p < r”,结果是不变的,一样可以正常排序。但是我debug时发现,如果用p < r,当分治到只有2个元素是,还会再分,直到分治到只有一个元素,而合并时就是没有元素的数组和只有一个元素的数组进行合并,平白多了一层递归,和一次没有用的合并。改成“p + 1 < r”后,就没有这个问题了,分治到2个元素为止,2个元素时返回(退出一层递归),交个merge函数去合并。
6,我在上面即用了System的arraycopy函数,又用了Arrays的copyOfRange,我的本意是不想用java.util包的东西的(接口除外),希望不熟悉API的初学者也可以看懂所有的代码。但是细看copyOfRange后,发现里面也就是新建一个数组,调用System的arraycopy函数来复制,还是很容易理解的。现在这篇东西主要讲分治,所以copyOfRange的细节就不讲述了,有兴趣的人可以自己去看看,还是很好玩的。
7,结合5,6两点,Java的数组的上下限,System的arraycopy的参数的意义(主要是位置参数和长度参数),Arrays的copyOfRange的参数的意义(复制的是由from和to参数定义的前闭后开区间),这3样混在一起,会发现,伪代码和Java实现的样子,看上去会很不同。
8,和前面的插入排序一样,这里分治排序Java的实现里面,是直接改变被排序的数组里面的内容的。
9,MERGE伪代码里面的1到7行,在Java实现里面就只需要2句话,API真是强大啊(或者说会这么用API的人,真是强大啊。哈哈。)。MERGE伪代码里面的8,9行,一点也不优雅,被俺好不犹豫的舍弃了。后面的for循环,做的事儿是一样的,但是我的代码比伪代码要更高效一点。不需要循环整个被排序区间,只要循环到左右两段被排序区间的任意一段遍历完成就行。遍历完后,如果是左段先结束,那么什么都不用做,排序就已经好了,因为右段本身就是已经排好的;如果是右段先结束,那么左段还剩下的元素要紧跟着,复制到已经排好的数组元素的后面。当然,Java更高效的原因是存在数组复制的API,而不是伪代码的错(不优雅的“凭空增加一个数组元素,往里面赋值无限大”除外)。

分治法具体实例 分治法——见名知意,即分而治之,从而得到我们想要的最终结果。分治法的思想是将一个规模为N的问题分解为k个较小的子问题,这些子问题遵循的原则就是互相独立且与原问题相同。下面我们就用具体的例子来理解分治法的算法思想。例题:一个装有 16 枚硬币的袋子,16 枚硬币中有一个是伪造的,并且那个伪造的硬币比真的硬币要轻。现有一台可用来比较两组硬币重量的仪器,请使用分治法设计一个算法,可以找出那枚伪造的硬币。... 阅读详情

相关推荐

算法导论(第三版)学习资源大全

本文还有配套的精品资源,点击获取 简介:《算法导论》第三版是一本详细介绍算法设计、分析和复杂性理论的计算机科学经典。这本书不仅全面覆盖了现代算法的新内容,还包括了基础概念、图算法、动态规划等关键章节,通过实例和代码帮助读者理解抽象算法。每一章都配有习题,用于练习和巩固知识。书中还包含了答案部分,供读者验证和提升理解。英文版《算法导论》对提升专业英语水平也有很大帮助。本书是学...

weixin_42315569的博客 1210

根据算法导论用java实现的b-tree

B-tree(多路搜索树),数据结构的一种,使用B-tree结构可以显著减少定位记录时所经历的中间过程,从而加快存取速度。 算法导论18章介绍的B-TREE 特性: 1、每个叶结点具有相同的深度。 2、假如树的度为T(子节点数),则根节点的关键字最少1个,最多2t-1个,非根节点,最少 t-1个,最多2t-1个。 3、根最少2个子节点,最多2t个子节点,非根非叶子节点,至少t个子节点,最多2t个...

q364035622的专栏 171

算法导论-java

算法导论:概述基本算法!对一个编程人员来说,算法很重要,一个好的算法,可以让你的软件运行效果好

【算法导论】红黑树 java实现

PS:本文章的理论知识来自《数据结构和算法 java描述》 平衡的补救 红黑树的平衡是在插入、删除的过程中取得的。对一个要插入的数据项,插入例程要检查不会破坏树一定的特征。如果破坏了,程序就会进行纠正,根据需要更改树的结构。通过维持树的特征,保持了树的平衡。 红-黑规则 每一个节点不是红色的就是黑色的 根总是黑色的 如果节点是红色的,则它的子节点必须是黑色的(...

HongJunxin 259

C语言实现分治法实例

主要为大家详细介绍了C语言实现分治法的实例,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

从原理图到代码:深入解析SX1278 LoRa模块与STM32的SPI通信驱动(附完整工程)

本文深入解析了SX1278 LoRa模块与STM32的SPI通信驱动实现,从硬件原理图到完整工程代码,详细介绍了LoRa技术的通信原理、寄存器配置、SPI接口设计及低功耗优化策略。适合物联网开发者和嵌入式工程师提升远距离无线通信能力,附完整工程代码助力快速开发。

weixin_42715608的博客 423

Java算法,分治算法一文介绍完成

分治算法(divide-and-conquer algorithm)是一种通过把一个复杂的问题分解为若干个相对简单的子问题,并且子问题之间相互独立,求解子问题然后将其组合起来,就得到原问题的解的计算机算法。举例如求解一个有序数组中的最大值,可以采用分治算法来求解,将数组拆分成两个子数组,对比两个子数组中的最大值,就可以求出数组的最大值。(1)分解:将大规模的问题,分解成若干个子问题,如果每个独立的子问题,都可以很容易地求解,那么原问题也可以被求解。1. 分治算法可能产生大量不必要的运算,降低算法效率;

qwert 866

基恩士PLC编程避坑指南:局部变量@前缀的3个隐藏陷阱与实战解决方案

本文深入剖析了基恩士PLC编程中使用@前缀创建局部变量的三大隐藏陷阱,包括在线调试时的数据丢失、数据类型冲突以及子程序复用时的地址覆盖问题。针对每个陷阱,提供了预定义变量、强类型规范和基址参数传递等实战解决方案,帮助中高级工程师提升代码健壮性与可维护性。

weixin_29171087的博客 102

算法导论——分治法、归并排序——伪代码和Java实现

第二章第三节:分治法 我们首先先介绍分治法。分治法的思想:将原问题分解为几个规模较小但类似于原问题的子问题,递归地求解这些子问题,然后在合并这些子问题的解来解决原问题的解。     还是拿扑克牌举例子,假设桌上有两堆牌面朝上的牌(牌面朝上:有值),每堆都已排序,最小的牌在顶上。我们希望把这两堆牌合并成单一的排好序的输出堆,牌面朝下地放在桌上。应该怎么做呢...

达的程序员日记 3204

【AI平台】n8n入门2:第一个工作流,调用本地大模型

n8n是一款开源的,专注于AI工作流构建,支持灵活的自定义与集成。就是可以把大模型和其他工具联合起来,这就厉害了。而且,免费功能又强大,目前很火,来研究一下。

正经教主是个热衷于正经学习分享的教主。 4531

【机械臂算法】机械臂动力学参数辨识仿真

本文以puma560m机械臂为例子进行动力学参数辨识的讲解,puma560m可以在robotic toolbox中找到,这里以它真实机械臂对他的动力学参数进行辨识。此外这里还有要说的是,机械臂参数辨识其实是一个系统工程,其中和系统的机械、电子、嵌入式都有着很深的联系,并不是仿真这么简单的。

vrijheid的博客 7834

java分治合并_算法导论2--分治算法合并排序

分治算法的步骤分治法解题的一般步骤:(1)分解,将要解决的问题划分成若干规模较小的同类问题;(2)求解,当子问题划分得足够小时,用较简单的方法解决;(3)合并,按原问题的要求,将子问题的解逐层合并构成原问题的解。合并排序算法 伪代码megre(a,p,q,r)n1=q-p+1n2=r-qcreate arrays L[0,1,...n1] and R[0,1,..n2]for i=0 to n1L...

weixin_28900461的博客 293

IC面试常考题 Verilog三分频电路设计(占空比50%,三分之一,三分之二)

实现三分频电路最简单的是: 利用计数器实现。 时序图分析(本人比较懒,平常科研忙,所以直接手画时序图了,懒得用软件画了): 直接上图分析:利用计数器每隔三个周期信号翻转一次,同时在不同的计数下翻转得到的同步信号 clk_1和clk_2,再利用异或即可实现出一个不同占空比的三分频信号(同样的方法也可扩展到其他奇数分频设计中)。 例如占空比50%: module Div_three( input clk, input rst_n, output div_three ); reg

qq_41884662的博客 1万+

Java实现算法导论中最近点对问题分治法

最近点对问题:给定平面上的N个点,找出距离最近的两个点。分治法: 1 )如果数组长度(即点的个数,一般≤3)在一定范围内时直接求出最近点,蛮力求解,递归退出条件; 2)求出这些点的X坐标的中位数mid 3)以mid为界将所有点分为两组,分表放在表T1、T2中 4)将T1、T2表转换为数组S1、S2,并将S1、S2分别按X坐标升序排列 5)求S1中的点的最近距离 ...

u011250186的博客 1536

在 ABAP 环境中创建 Job Catalog Entry 和 Job Template 的完整实践指南

摘要:本文介绍了SAP BTP ABAP环境中Application Job的云原生解决方案,对比传统后台作业模式。重点阐述了Job Catalog Entry和Job Template两大核心概念,通过库存重估业务场景演示如何实现可调度类、创建Job Catalog Entry及Job Template。文章详细说明了从ABAP类到Job Catalog Entry再到Job Template的完整链路,并分享实际项目中的设计经验和注意事项,帮助开发者将传统后台作业迁移到Application Job框架

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 232

人形机器人硬件电路设计入门

人形机器人属于。

blotemj.blog.youkuaiyun.com 229

算法导论 分析分治算法

分析分治算法 许多有用的算法在结构上是递归:为了解决一个给定的问题,算法一次或多次递归地调用其自身以解决紧密相关的若干子问题,这些算法典型地遵循分治法的思想: 将原问题分解为几个规模较小但类似于原问题的子问题,递归地求解这些子问题,然后再合并这些子问题的解来建立原问题的解。 分治模式在每层递归时都有三个步骤: 分解原问题为若干子问题,这些子问题是原问题的规模较小的实例。 解决这些子问题,递归地求...

qq_41946874的博客 537

OpenClaw实战系列10(完结篇):企业级应用实战案例——从0到1搭建智能客服系统

本文以一家跨境电商公司为例,从需求分析、系统设计、分步搭建到上线运营,完整呈现智能客服系统的落地全过程。所有配置命令和截图均来自实测环境,你可以直接复制使用。

PeterPan的博客 1305

分治策略(1)——算法导论(3)

1. 从一个股价的问题说起 假如你获得了一种可以预测未来某公司股价的能力。下图是你预测的股价情况,那么你会在哪一天买入,哪一天卖出呢? 你可能认为可以在这17天当中的股价最低的那天(第7天)买入,然后在之后的股价最高的那天(第11天)卖出;或者反过来,在整段时间内股价最高的那天卖出,然后在之前的股价最低的那天买入。如果这种策略是可行的,那么确定最大收益将非常简单。但事实是,这种...

dayin201608的博客 184

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

分治算法

分治算法分析,及几道经典的分治算法

xiuweikang的专栏 930

OV9734 DATASHEET,完整规格书

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

java最近点对分治算法_算法导论-分治法-最近点对-HDOJ1007

HDOJ1007的原题目是求出在不同时套中两个玩具的前提下,圆圈的最大半径。问题翻译过来就是求解最近点对的问题,这个问题是经典的分治法问题。毫无疑问,通过暴力手段列举所有的点对并计算这些点对的距离,找出最小的一组,可以得到最后的结果。但是,这道题的数据规模非常大,所以,这种传统的方法肯定行不通。我试过,hdoj是超时的。我对原博客的第3步和第4步有不同的看法。原博客步骤:1.读取数据,并将点按横坐...

weixin_27717759的博客 413

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

学算法要读《算法导论》吗?

如分治法等,此外在数据结构中创建哨兵节点的技巧也在链表章节中也描述。我认为它的前十六章加上第二十二章用来学习基础的算法已经足够了。开篇我说这本书像鸡尾酒,因为。

京东科技开发者 921

《算法导论》-分治策略,矩阵相乘Strassen算法(伪代码,Java)

如果要计算上述矩阵,最简单的通用方法是通过三个循环也就是复杂度为O(n^3).而Strassen算法的特点是适用于比较大的矩阵,通过递归划分,再用上述公式解决,创建10个n/2小矩阵,递归计算7个矩阵。

qq_44242804的博客 1855

0402最大子数组-分治策略-算法导论第三版

0402最大子数组-分治策略-算法导论第三版

gaogzhen的博客 699

《算法导论》-分治策略-最大子数组问题,理解与实现(Java,C++)

关于最大子数组问题如果采用暴力破解法将会很容易实现,但是暴力破解复杂度可想而知,所有如果采用分治策略可以大大减少运行时间,下面将分析分治策略如何解决这个问题,通过伪代码来表示执行过程,并用Java,C++进行实现.

qq_44242804的博客 794
上一篇: 《算法导论的Java实现》 1_1.1 插入排序
下一篇: 《算法导论的Java实现》 7 堆排序
chen09
博客等级 码龄19年 158粉丝 18原创
评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值