在计算机科学中,分治法是一种很重要的算法。字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)……
分治法简介
任何一个可以用计算机求解的问题所需的计算时间都与其规模有关。问题的规模越小,越容易直接求解,解题所需的计算时间也越少。例如,对于n个元素的排序问题,当n=1时,不需任何计算。
n=2时,只要作一次比较即可排好序。n=3时只要作3次比较即可,…。
而当n较大时,问题就不那么容易处理了。要想直接解决一个规模较大的问题,有时是相当困难的。
分治法的设计思想是,将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。
分治策略是:
对于一个规模为n的问题,若该问题可以容易地解决(比如说规模n较小)则直接解决,否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地解这些子问题,然后将各子问题的解合并得到原问题的解。这种算法设计策略叫做分治法。
如果原问题可分割成k个子问题,1<k≤n ,且这些子问题都可解并可利用这些子问题的解求出原问题的解,那么这种分治法就是可行的。由分治法产生的子问题往往是原问题的较小模式,这就为使用递归技术提供了方便。在这种情况下,反复应用分治手段,可以使子问题与原问题类型一致而其规模却不断缩小,最终使子问题缩小到很容易直接求出其解。这自然导致递归过程的产生。分治与递归像一对孪生兄弟,经常同时应用在算法设计之中,并由此产生许多高效算法。
分治法所能解决的问题一般具有以下几个特征:
1) 该问题的规模缩小到一定的程度就可以容易地解决
2) 该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质。
3) 利用该问题分解出的子问题的解可以合并为该问题的解;
4) 该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子问题。
上述的第一条特征是绝大多数问题都可以满足的,因为问题的计算复杂性一般是随着问题规模的增加而增加;第二条特征是应用分治法的前提它也是大多数问题可以满足的,此特征反映了递归思想的应用;第三条特征是关键,能否利用分治法完全取决于问题是否具有第三条特征,如果具备了第一条和第二条特征,而不具备第三条特征,则可以考虑用贪心法或动态规划法。第四条特征涉及到分治法的效率,如果各子问题是不独立的则分治法要做许多不必要的工作,重复地解公共的子问题,此时虽然可用分治法,但一般用动态规划法较好。
进一步说明
当问题太过复杂而无法直接求解时,一个最简单的方法就是,把问题分解成相互独立的子问题分别求解,再想办法把子问题的解合并成整个问题的解。如果子问题还是比较复杂而无法直接求解,可以再次对其进行分解,就像李恕权所做的那样。不过对于算法来说,由于通常输入的元素个数(或者说计算的复杂度)是不确定的,导致我们无法确定需要分解多少次才能把子问题简化到可以直接求解的程度,所以我们在做分解的时候不能像李恕权那样自由,一般来说都必须让子问题与原问题具有相似的结构、只是规模较小,这样才能递归地进行分解、解决。这种先分解再合并的解决问题的方法,就叫做分治法(divide-and-conquer)。
分治法的基本步骤
分解(Divide):将原问题分解成一系列子问题;
解决(Conquer):递归地解决各子问题。若子问题足够小,则直接求解;
合并(Combine):将子问题的结果合并成原问题的解。
java编程实现分治法归并排序,附有结果
public class Mergesort { public static void merge(int[]a,int low,int mid,int high){ //对两组已经排序的数组进行合并 int[]b=new int[high-low+1]; int s=low; int t=mid+1; int k=0; while(s<=mid&&t<=high){ if(a[s]<=a[t]) b[k++]=a[s++]; else b[k++]=a[t++]; } while(s<=mid) b[k++]=a[s++]; while(t<=high) b[k++]=a[t++]; for(int i=0;i<b.length;i++){ a[low+i]=b[i]; } } public static void mergesort(int a[],int low,int high){ //对数组进行递归排序 if(low<high){ mergesort(a,low,(low+high)/2); mergesort(a,(low+high)/2+1,high); merge(a,low,(high+low)/2,high); } } public static void main(String[]args){ int[]a={49,38,65,92,76,13,27}; System.out.println("排序前数组为:"); for(int i=0;i<a.length;i++){ System.out.print(a[i]+" "); } mergesort(a,0,a.length-1); System.out.println("\n排序后数组为:"); for(int i=0;i<a.length;i++){ System.out.print(a[i]+" "); } } }
运行结果:
排序前数组为:
49 38 65 92 76 13 27
排序后数组为:13 27 38 49 65 76 92
相关推荐
使用java编写 用分治法实现对于平面上最近点对的查找 使用Swing作为界面
### Java编程实现分治法归并排序 #### 分治法基本思想 分治法是一种将大问题分解成小问题,并通过解决这些小问题来解决原始问题的方法。这种方法的基本步骤包括: 1. **分解**:将一个问题分解为若干个规模较小的...
算法课程设计——分治法(java实现) 本课程设计报告的主要内容是对分治法的详细分析和讲解,并使用 Java 语言对其进行实现。分治法是一种经典的排序算法,它的主要思想是将问题分解为两个子序列,然后对子序列进行...
**标题解析:**“分治法求最近点对”指的是使用分治策略来解决寻找二维空间中距离最近的两个点的问题。...通过深入学习和实践,可以提升对分治法和Java编程的理解,同时也能锻炼到算法设计和问题解决的能力。
【Java另类分治法解决凸包问题】 在计算机图形学和算法设计中,凸包问题是一个经典问题,它的目标是从一组二维平面上的点集找到一个最小的凸多边形,该多边形包含所有点。在这个问题中,我们采用了一种基于分治法的...
它的主要思想是分治法,即将大问题分解为小问题来解决。在快速排序中,我们选择一个基准值(pivot),然后将数组分为两部分:一部分包含所有小于基准的元素,另一部分包含所有大于或等于基准的元素。这个过程通过...
在计算机科学领域,矩阵相乘是一项基础且重要的计算任务,特别是在图像处理、机器学习和线性代数等领域。当处理的矩阵规模非常大时,普通...通过Java实现,我们可以更好地掌握这一算法,并将其运用到实际的编程挑战中。
本文将详细介绍如何运用分治法解决“棋盘覆盖”这一经典问题,并给出相应的Java实现代码。 #### 二、问题定义 假设有一个\(2^k \times 2^k\)个方格组成的棋盘,其中恰好有一个特殊方格与众不同(通常表示为缺失或...
**分治法求众数** 分治法是一种重要的算法设计策略,它将复杂的问题分解成较小的子问题,然后递归地解决这些子问题,最后将子问题的解合并成原问题的解。在这个实验中,我们应用分治法来寻找数组中的众数,即出现...
在本项目“最短距离点对分治法实现 Java”中,我们将探讨如何使用分治法来解决点对之间最短距离的问题,并结合Java编程语言以及Java Swing库创建一个图形化的用户界面。 首先,我们需要理解分治法的基本思想。分治...
java用分治法实现赛程安排的程序。N个参赛队员,每个队员间比赛一场,要求在N-1天内完成。输出结果第一行(或者第一列)当成队员标号,从第二行开始作为第一天,到第N-1天的比赛对手安排。
(2)考虑n不是2的幂次方,n为偶数的情形,设计一个传统方法与的Strassen算法相结合的矩阵相乘算法,取n=12实现分治递归(可以有多种方案实现); 矩阵A,B元素自动生成,限定矩阵元素在0-10之间。
本篇文章将详细介绍如何使用分治法来解决最近对问题,并提供一个Java实现的例子。 #### 二、分治法简介 分治法是一种将复杂问题分解成较小的子问题来求解的算法策略。这些子问题通常与原问题属于同一类型,且规模...
**实验4 分治法1** 分治法是计算机科学中一种重要的算法设计策略,它将一个大问题分解为若干个小问题来解决。这种思想源于“分而治之”,旨在通过解决小规模问题来构建大规模问题的解决方案。在这个实验中,我们将...
使用JAVA解决残缺棋盘覆盖问题:一个n*n的棋盘上有一个缺陷点,该点不能被覆盖,剩下的格子全部用三盒板覆盖。应用的是分治法。
总之,通过分治法和Java编程,我们可以有效地解决比赛日程安排问题,实现一个灵活且高效的解决方案。这不仅锻炼了我们的算法思维,还提高了我们处理实际问题的能力。在实际应用中,这种问题解决方式也可以扩展到其他...
分治法实现棋盘的“3-L形”完全覆盖,java实现。
### 最近对问题:分治法与蛮力法 #### 一、背景介绍 最近对问题(Closest Pair Problem)是指在平面上找到距离最近的两个点。这个问题在计算几何和计算机科学领域有着广泛的应用,比如地图应用中的路径规划、模式...
java实现strassen算法 运用了分治法和strassen原理 课堂作业
分治法是一种常用的算法设计策略,它将大问题分解为若干个规模较小、相互独立且与原问题形式相同的子问题来解决。分治法通常包括三个步骤:分解、解决和合并。通过递归地应用这些步骤,最终将子问题的答案组合成原...