一针见血分治算法

    对于一个程序员来说,算法是必不可少的。现在的算法五花八门,让人有点找不到北,不过归根结底,也就那么几类,其他算法都是这些算法的优化或者派生。

    今天就跟大家说说分治法。

【算法本质】

    分治法是得益于“大禹治水”的思想研究得来的算法。本质为“分而治之”。俗一点就是“大事化小,小事化了”。

【设计思想】

    将一个难以直接解决的大问题分解成一些规模较小的相同问题以便各个击破,分而治之。如果规模为n的问题,可以分解成k个子问题,1<k<=n,这些子问题相互独立切与原问题相同,分治法产生的子问题,往往是原问题的较小模式,这就为递归技术提供了方便。

【算法递归步骤】

    (一)分解。将原问题分解成一系列子问题。

    (二)求解。递归地求解各子问题。若子问题足够小,则直接求解。

    (三)合并。将子问题的解合并成原问题的解。

【沙场点兵】

这是一道软考题。QUICKSORT函数为快速排序,PARTITION函数作用为对数组A排序,并返回枢轴元素位置下标。

举一个实例:对数组A={ 9,3,5,8,7} 进行排序。

跟着代码走,现在p=0,r=4,所以p<r,执行q=PARTITION(A,p,r),进入第一次排序。

x=A[r]=7,i=p-1=-1,j的变化从p-》r-1,即0-》3。循环体内,比较A[j]与x的值:

 

j=0时,A[j]=9>x。j=1进入下次循环,如图;

 

j=1时,A[j]=3<x,i=i+1=0,交换A[i]和A[j]。j=2进入下次循环,如图;

 

j=2时,A[j]=8>x,j=3进入下次循环,如图;

 

j=3时,A[j]=4<x,i=i+1=2,交换A[i]和A[j],如图。j=4>r-1,退出循环;

 

根据分治算法,由枢轴元素为界限,把原数组划分为2组,枢轴元素左边的元素>枢轴元素>枢轴元素右边的元素。所以,我们现在要做的就是把x的值与i+1所在位置的元素进行交换。即A[i+1]与A[r]交换。

 

最后把枢轴元素的下标返回给q,即q=2。第一趟排序完成。然后执行QUICKSORT(A,p,q-1)和QUICKSORT(A,q+1,r)。即分别对划分的子数组进行快速排序。看完整的图解:

 

不难发现,在分治策略中,由于子问题与原问题在结构和解法上的相似性,用分治方法解决的问题,大都采用了递归的形式。在各种排序方法中,如归并排序、堆排序、快速排序等,都存在有分治的思想。

 

时间: 2024-09-27 22:02:54

一针见血分治算法的相关文章

【算法】2 由股票收益问题再看分治算法和递归式

回顾分治算法 分治算法的英文名叫做"divide and conquer",它的意思是将一块领土分解为若干块小部分,然后一块块的占领征服,让它们彼此异化.这就是英国人的军事策略,但我们今天要看的是算法. 如前所述,分治算法有3步,在上一篇中已有介绍,它们对应的英文名分别是:divide.conquer.combine. 接下来我们通过多个小算法来深化对分治算法的理解. 二分查找算法 问题描述:在已排序的数组A中查找是否存在数字n. 1)分:取得数组A中的中间数,并将其与n比较 2)治:

五大常用算法之一:分治算法

分治算法 一.基本概念    在计算机科学中,分治法是一种很重要的算法.字面上的解释是"分而治之",就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小 的子问题--直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并.这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立 叶变换(快速傅立叶变换)--     任何一个可以用计算机求解的问题所需的计算时间都与其规模有关.问题的规模越小,越容易直接求解,解题所需的计算时间也越少.例如,对于n

《算法技术手册》一1.3.2 分治算法

1.3.2 分治算法 我们也可以将点按x坐标从左到右排序(如果x坐标相同,就按照y坐标排序),就能将这个问题分成两个稍微小一点的子问题.首先可以从点p0到pn-1,按照从左到右.顺时针的顺序计算出一个上半部分凸包,然后用同样的方法从pn-1到p0,按照从右到左.同样是顺时针的顺序计算出下半部分凸包.凸包扫描算法(将在第9章中介绍)可以计算出这些半凸包(见图1-4),然后将结果合并在一起生成最终的凸包. 图1-4:合并上.下部分凸包组成完整凸包

分治算法与递归的关系

问题描述 分治算法与递归的关系 分治算法会用到递归,递归函数的复杂度都普遍高于非递归函数,请问分治算法使用递归的意义是什么,对分治的复杂度有什么影响呢 解决方案 递归函数的复杂度都普遍高于非递归函数 谁告诉你的.算法复杂度是算法本身决定的,而不是递归不递归决定的. 分治算法用递归是最天然.简单和自然的事情. 但是对于比较复杂的算法,受制于堆栈上存储有限,在递归层次很深的情况下,改写为形式上的非递归(注意,形式上,也就是不用系统堆栈和函数调用,但本质上还是递归算法).这只是一种技巧而已. 解决方案

《算法设计与分析》一一2.3 “分治递归”求解

2.3 "分治递归"求解 递归是一种基本的算法设计方法,而递归算法的代价往往可以用递归方程来描述,因而解递归方程就成为递归算法分析的重要技术.分治策略(divide and conquer)是一种简单而有效的算法设计策略(详见第三部分各章节的讨论),源自于分治算法分析的一类特定形式的递归方程我们称之为"分治递归"(divide and conquer recursion).本节着重讨论"分治递归"的求解方法.2.3.1 替换法 有一种"

《算法技术手册》一3.6.2 分治

3.6.2 分治 分治通常是将一个规模为n的问题划分成两个独立的子问题,其中每个子问题的规模约为n/2.大部分时候分治策略是递归形式的,并且会有简单易懂的基本条件用于结束递归.此外,在计算出两个较小问题的解之后,还必须要有一些计算来根据子问题的解计算出原问题的解.下面来看一个例子:求包含n个数的数组中的最大元素.例3-2展示了如何将原问题分解成两个子问题并通过递归求解.通常,最大值一般是两个子集各自的最大值中比较大的那一个.仔细观察尾递归触发的条件,即子集中只有一个元素vals[left]返回.

【万字总结】以插排和分治为例来看如何分析与设计算法

插入排序及其解决思路 算法的作用自然不用多说,无论是在校学生,还是已经工作多年,只要想在计算机这条道路走得更远,算法都是必不可少的. 就像编程语言中的"Hello World!"程序一般,学习算法一开始学的便是排序算法.排序问题在日常生活中也是很常见的,说得专业点: 输入是:n个数的一个序列<a1,a2,...,an−1,an> 输出是:这n个数的一个全新的序列<a,1,a,2,...,a,n−1,a,n>,其特征是a,1≤a,2≤...≤a,n−1≤a,n 举

浅谈算法和数据结构 三 合并排序

合并排序,顾名思义,就是通过将两个有序的序列合并为一个大的有序的序列的方式来实现排序.合并排序是一种典型的分治算法:首先将序列分为两部分,然后对每一部分进行循环递归的排序,然后逐个将结果进行合并. 合并排序最大的优点是它的时间复杂度为O(nlgn),这个是我们之前的选择排序和插入排序所达不到的.他还是一种稳定性排序,也就是相等的元素在序列中的相对位置在排序前后不会发生变化.他的唯一缺点是,需要利用额外的N的空间来进行排序. 一 原理 合并排序依赖于合并操作,即将两个已经排序的序列合并成一个序列,

(算法导论习题解problem2.4)寻找一个序列中逆序对的数量

一个序列的逆序对是这样的两个元素, 对于序列A而言, i>j且A[i]<A[j], 于是A[i]和A[j]就形成一个逆序对. 研究一个序列中逆序对的数量是有实际意义的, 对于插入排序而言, 它排序的时间与待排序序列的逆序对数量成正比. 下面给出求出一个序列中逆序对数量的算法,类似于归并排序中使用的分治算法:一个序列的逆序对数量为它的左半部分逆序对的数量,加上右半部分逆序对的数量, 最后在合并的时候左半部分元素大于右半部分元素的数量.这几乎和归并算法的过程一模一样,只是在归并的时候加入了计数的操