Chapter-3 分治策略
分治法的简单描述

分治法的简单描述分治法是一种算法设计的思想,它将一个大问题分解为多个小问题,通过解决小问题来解决大问题。
这种思想的应用非常广泛,可以用来解决各种问题,比如排序、查找、计算等等。
下面我们来详细介绍一下分治法的基本原理和应用。
分治法的基本原理是将一个问题分解为多个独立的子问题,然后对每个子问题进行求解,最后将子问题的解合并起来得到原问题的解。
这种分解和合并的过程可以递归地进行,直到问题变得足够简单,可以直接求解为止。
在应用分治法解决问题时,需要满足以下三个条件:1.原问题可以分解为多个独立的子问题;2.子问题的结构与原问题相同,只是规模更小;3.子问题的解可以合并得到原问题的解。
接下来我们来看两个分治法的经典应用:归并排序和快速排序。
归并排序是一种经典的排序算法,它的基本思想就是使用分治法将一个无序的序列分解为多个有序的子序列,然后再将这些子序列合并起来得到一个有序的序列。
具体的步骤如下:1.将序列分成两个子序列,分别对这两个子序列进行归并排序;2.将两个有序的子序列合并成一个有序的序列。
归并排序的时间复杂度为O(nlogn),其中n是序列的长度。
它的空间复杂度为O(n),其中n是序列的长度。
快速排序是另一种经典的排序算法,它的基本思想也是使用分治法将一个无序的序列分解为多个有序的子序列,然后再将这些子序列合并起来得到一个有序的序列。
具体的步骤如下:1.从序列中选择一个元素作为基准值,将序列分成两个子序列,一个小于基准值,一个大于基准值;2.分别对这两个子序列进行快速排序;3.将两个有序的子序列合并成一个有序的序列。
快速排序的时间复杂度取决于基准值的选择,最坏情况下的时间复杂度为O(n^2),其中n是序列的长度。
但是平均情况下的时间复杂度为O(nlogn),空间复杂度为O(logn)。
除了排序问题,分治法还可以应用于其他一些问题,比如最大子数组和问题。
给定一个整数数组,找到一个具有最大和的连续子数组。
分治法解决问题的步骤

分治法解决问题的步骤一、基础概念类题目(1 - 5题)题目1:简述分治法解决问题的基本步骤。
解析:分治法解决问题主要有三个步骤:1. 分解(Divide):将原问题分解为若干个规模较小、相互独立且与原问题形式相同的子问题。
例如,对于排序问题,可将一个大的数组分成两个较小的子数组。
2. 求解(Conquer):递归地求解这些子问题。
如果子问题规模足够小,则直接求解(通常是一些简单的基础情况)。
对于小到只有一个元素的子数组,它本身就是有序的。
3. 合并(Combine):将各个子问题的解合并为原问题的解。
在排序中,将两个已排序的子数组合并成一个大的有序数组。
题目2:在分治法中,分解原问题时需要遵循哪些原则?解析:1. 子问题规模更小:分解后的子问题规模要比原问题小,这样才能逐步简化问题。
例如在归并排序中,不断将数组对半分,子数组的长度不断减小。
2. 子问题相互独立:子问题之间应该尽量没有相互依赖关系。
以矩阵乘法的分治算法为例,划分后的子矩阵乘法之间相互独立进行计算。
3. 子问题与原问题形式相同:方便递归求解。
如二分查找中,每次查找的子区间仍然是一个有序区间,和原始的有序区间查找问题形式相同。
题目3:分治法中的“求解”步骤,如果子问题规模小到什么程度可以直接求解?解析:当子问题规模小到可以用简单的、直接的方法(如常量时间或线性时间复杂度的方法)解决时,就可以直接求解。
例如,在求数组中的最大最小值问题中,当子数组只有一个元素时,这个元素既是最大值也是最小值,可以直接得出结果。
题目4:分治法的“合并”步骤有什么重要性?解析:1. 构建完整解:它将各个子问题的解组合起来形成原问题的解。
例如在归并排序中,单独的两个子数组排序好后,只有通过合并操作才能得到整个数组的有序排列。
2. 保证算法正确性:如果合并步骤不正确,即使子问题求解正确,也无法得到原问题的正确答案。
例如在分治算法计算斐波那契数列时,合并不同子问题的结果来得到正确的斐波那契数是很关键的。
如何应用分治算法求解问题

如何应用分治算法求解问题分治算法,英文名为Divide and Conquer Algorithm,是一种高效的算法设计策略,在计算机科学中有着广泛的应用。
该算法将一个大问题分解成多个小问题,各自独立地解决,再将结果合并起来得到最终结果。
在本文中,我们将阐述如何应用分治算法求解问题,并通过几个实例来具体说明该算法的应用。
一、分治算法的原理分治算法的核心思想是将一个大问题分解成若干个小问题来解决,然后将这些小问题的解组合起来生成大问题的解。
其具体步骤如下:1. 分解:将原问题划分成若干个规模较小的子问题。
2. 解决:递归地解决每个子问题。
如果子问题足够小,则直接求解。
3. 合并:将所有子问题的解合并成原问题的解。
分治算法的主要优点在于它可以有效地缩小问题规模,从而缩短整个算法的执行时间。
另外,该算法天然适用于并行计算,因为每个子问题都是独立求解的。
二、分治算法的应用分治算法在各种领域都有广泛应用,包括数学、自然科学、计算机科学等。
以计算机科学领域为例,分治算法常常用于解决以下类型的问题:1. 排序问题2. 查找问题3. 字符串匹配问题4. 最大子序列和问题5. 矩阵乘法问题6. 图形问题下面我们将一一讲解这些问题的分治算法实现。
1. 排序问题排序问题是在一组数据中将其按指定规律进行排列的问题。
在计算机科学中,排序算法是十分重要的一类算法。
其中,分治算法由于其高效性和可并行性被广泛应用。
常用的分治排序算法包括归并排序和快速排序。
归并排序的基本思想是将待排序元素以中心点为界分成两个序列,对每个序列进行排序,然后将两个序列合并成一个有序序列;而快速排序则利用了分割的思想,通过每次选取一个元素作为“轴点”,将数组分成小于轴点和大于轴点的两部分,对这两部分分别进行快速排序。
2. 查找问题查找问题是在一组数据中寻找某个元素的问题。
分治算法在查找问题中的应用主要体现在二分查找中。
在二分查找中,我们首先将已排序的数组分成两半,在其中一半中查找目标值。
分治法

顾铁成
1
引例:称硬币
如果给你一个装有16枚硬币的袋子,其中有一
枚是假的,并且其重与真硬币不同。你能不能 用最少的比较次数,找出这个假币?
为了帮助你完成这个任务,将提供一台可用来 比较两组硬币重量的仪器,利用这台仪器,可
以知道两组硬币的重量是否相同。
2
引例:称硬币
常规的解决方法是先将这些硬币分成两
15
当 k = 1 时,各种可能的残缺棋盘
16
三格板的四个不同方向
17
【输入】
第一行输入棋盘 的总行数,第二 行输入残缺棋盘 的格子坐标。
【样例输入】 4
4 1
【样例输出】 2 2 3 3 2 1 1 3 4 4 1 5
【输出】
覆盖的矩阵图。
0 4 5 5
18
问题分析
很明显,当K=0时,是不需要三格板的,而当
24
【样例输入】 5 3 23 8 91 56 4 【样例输出】 1
25
问题分析
对于一组混乱无序的数来说,要找到第k
小的元素,通常要经过两个步骤才能实 现:
第一步:将所有的数进行排序; 第二步:确定第k个位置上的数。
26
问题分析
传统的排序算法(插入排序、选择排序
、冒泡排序等)大家都已经很熟悉了, 但已学过的排序方法无论从速度上பைடு நூலகம்还 是从稳定性方面,都不是最佳的。
将7作为一个参照数;
将这个数组中比7大的数放在7的左边; 比7大的数放在7的右边;
这样,我们就可以得到第一次数组的调整:
[ 4 2 6 6 1 ] 7 [ 10 22 9 8 ]
29
分治算法课程思政

分治算法课程思政引言:分治算法是一种重要的算法思想,它能够将复杂的问题分解为更小的子问题,并通过合并子问题的解来得到原问题的解。
在计算机科学领域中,分治算法被广泛应用于各种问题的求解,包括排序、搜索、图论等。
然而,分治算法不仅仅是一种技术,它也具有一定的思想内涵,与我们的思政课程有着紧密的关联。
一、分治算法的基本原理分治算法的基本原理可以概括为以下三个步骤:1. 分解:将原问题分解成若干个规模较小、相互独立且与原问题性质相同的子问题;2. 解决:递归地求解各个子问题。
如果子问题的规模足够小,则直接求解;3. 合并:将子问题的解合并成原问题的解。
二、分治算法的优势与应用1. 提高问题求解效率:通过将问题分解为更小的子问题,并利用子问题的解来解决原问题,分治算法能够提高问题的求解效率。
2. 并行计算:分治算法的特点是子问题之间相互独立,这使得分治算法能够很好地适应并行计算的需求。
3. 应用广泛:分治算法在各个领域都有广泛的应用,比如在排序算法中,快速排序和归并排序就是典型的分治算法;在图论中,最短路径算法和最小生成树算法也是基于分治思想。
三、分治算法与思政课程的关联1. 科学思维:分治算法能够帮助我们培养科学思维,通过将问题分解为更小的子问题,有助于我们理清问题的本质,形成系统化的思考方式。
2. 人文关怀:分治算法的思想也体现了人文关怀的一面。
通过将问题分解为更小的子问题,可以更加细致地对问题进行分析与解决,从而为人们提供更好的服务和保障。
3. 创新意识:分治算法的应用需要我们不断地创新和思考,通过将问题分解为更小的子问题,我们能够发现问题的更多解决思路,培养创新意识和创新能力。
4. 解决社会问题:分治算法在解决实际社会问题上具有重要意义。
通过将复杂的社会问题分解为更小的子问题,我们能够更好地理解和解决这些问题,为社会的发展和进步做出贡献。
结语:分治算法作为一种重要的算法思想,不仅具有技术的价值,更有着深刻的思想内涵。
分治算法

65 97
13 76
38 49 65 97
13 27 76
13 27 38 49 65 76 97
黑盒划分典型问题—合并排序
合并排序算法改进
从分治过程入手,容易消除mergeSort算法中的递归 调用
49 38 65 97 76 13 27
38 49
65 97
13 76
27
38 49 65 97
题的解,自底向上逐步求出原来问题的解。
T(n)
=
n
递归的概念
由分治法产生的子问题往往是原问题的较小模式,这 就为使用递归技术提供了方便。在这种情况下,反复 应用分治手段,可以使子问题与原问题类型一致而其 规模却不断缩小,最终使子问题缩小到很容易直接求 出其解。这自然导致递归过程的产生。
直接或间接地调用自身的算法称为递归算法。用函数 自身给出定义的函数称为递归函数。
黑盒划分典型问题—合并排序
【例5】合并排序
任务描述:任意给定一包含n个整数的集合,把n个整数按升序排列。 输入:每测试用例包括两行,第一行输入整数个数,第二行输入n个整 数,数与数之间用空格隔开。最后一行包含-1,表示输入结束。 输出:每组测试数据的结果输出占一行,输出按升序排列的n个整数。 样例输入:
13 27 76
13 27 38 49 65 76 97
黑盒划分典型问题—合并排序
黑盒划分典型问题—合并排序
合并排序算法改进
从分治过程入手,容易消除mergeSort算法中的递归调用 自然合并排序
49 38 65 97 76 13 27
49
38 65 97
76
13 27
38 49 65 97
黑盒划分典型问题—逆序对问题
分治算法主方法
分治算法主方法分治算法是一种算法设计策略,将问题分解成若干个规模较小且结构相似的子问题,然后递归地解决这些子问题,最后将子问题的解合并起来得到原问题的解。
分治算法主方法是指应用分治策略解决问题的通用模板,下面将详细介绍分治算法主方法的原理和应用。
一、原理分治算法主方法包含三个步骤:分解、解决和合并。
1. 分解:将原问题分解成若干个规模较小且结构相似的子问题。
分解的策略可以根据具体问题的特点来确定,通常是将原问题划分成两个或多个规模相等或相近的子问题。
2. 解决:递归地解决子问题。
当子问题的规模足够小时,可以直接求解。
否则,继续将子问题分解成更小的子问题,直到可以直接求解为止。
3. 合并:将子问题的解合并成原问题的解。
子问题的解可以通过递归得到,合并的操作可以根据具体问题的要求进行,通常是将子问题的解组合起来得到原问题的解。
二、应用分治算法主方法可以应用于解决各种问题,下面列举几个常见的应用场景。
1. 排序问题:如归并排序、快速排序等。
这些排序算法通过将待排序序列分解成若干个规模较小的子序列,然后递归地排序这些子序列,并将排好序的子序列合并起来得到最终的有序序列。
2. 查找问题:如二分查找。
二分查找通过将待查找的有序序列分解成两个规模相等的子序列,然后递归地在其中一个子序列中查找目标元素。
如果找到了目标元素,则返回其索引;如果未找到,则继续在另一个子序列中查找。
3. 求解最大子数组问题:给定一个整数数组,求其连续子数组中和最大的值。
最大子数组问题可以通过分治算法主方法求解。
将原数组分解成两个规模相等的子数组,分别求解左子数组和右子数组的最大子数组和,然后将其合并起来得到原数组的最大子数组和。
4. 求解最近对问题:给定平面上的n个点,求其中距离最近的两个点。
最近对问题可以通过分治算法主方法求解。
将平面上的点按照横坐标进行排序,然后将点集分解成两个规模相等的子集,分别求解左子集和右子集的最近对,然后将其合并起来得到原点集的最近对。
分治法的步骤
分治法的步骤分治法是一种常见的算法设计策略,它将问题分解成更小的子问题,然后递归地解决每个子问题,最后将这些子问题的解合并起来得到原问题的解。
下面将详细介绍分治法的步骤。
一、分治法的定义和基本思想分治法是一种算法设计策略,它将一个大问题分解成若干个相互独立且结构相同的小问题,递归地求解这些小问题,并将它们的结果组合起来得到原问题的解。
在实际应用中,分治法通常用于处理那些具有重复性质或者可以通过递归实现的计算任务。
二、分治法的步骤1. 分解:首先将原问题划分为若干个规模较小、结构相似且独立的子问题。
这个过程通常称为“分解”(divide)。
2. 解决:对每个子问题进行递归求解。
如果子问题足够小而可以直接求解,则直接求解。
这个过程通常称为“解决”(conquer)。
3. 合并:将所有子问题的结果合并成原问题的结果。
这个过程通常称为“合并”(combine)。
三、应用场景1. 排序算法:例如归并排序、快速排序等。
2. 查找算法:例如二分查找。
3. 图论算法:例如最大子数组、矩阵乘法、汉诺塔等。
四、分治法的优缺点1. 优点:分治法可以有效地解决一些具有重复性质或者可以通过递归实现的计算任务,具有较高的效率和可扩展性。
2. 缺点:分治法需要额外的空间来存储子问题的结果,而且在递归过程中可能会出现栈溢出等问题,需要进行合理的优化。
同时,如果分解得不够合理或者子问题之间存在依赖关系,则可能会导致算法效率下降。
五、总结分治法是一种常见的算法设计策略,它将一个大问题划分为若干个规模较小、结构相似且独立的子问题,并递归地求解这些子问题。
在实际应用中,分治法通常用于处理那些具有重复性质或者可以通过递归实现的计算任务。
虽然分治法具有较高的效率和可扩展性,但也存在额外空间开销和栈溢出等问题,需要进行合理优化。
分治算法探讨分治策略与应用场景
分治算法探讨分治策略与应用场景随着计算机科学的快速发展,算法成为了解决问题的重要工具。
其中,分治算法在很多场景下展现出强大的能力,被广泛应用于各个领域。
本文将探讨分治策略的原理和常见应用场景。
一、分治策略的基本原理分治策略是一种将大问题划分为细分的子问题,并通过解决子问题来解决原始问题的思想。
其基本思路可以概括为以下三个步骤:1. 分解:将原始问题划分为若干规模较小的子问题。
2. 解决:递归地解决各个子问题。
3. 合并:将各个子问题的解合并为原始问题的解。
通过将大问题递归地划分为越来越小的子问题,最终解决各个子问题,再将子问题的解合并为原始问题的解,分治策略能够高效地解决很多复杂的问题。
二、分治策略的应用场景1. 排序算法排序是计算机科学中一个重要的问题,各种排序算法都可以使用分治策略来实现。
例如,快速排序和归并排序就是使用分治策略的经典排序算法。
在快速排序中,通过选择一个基准元素将问题划分为两个子问题,然后递归地排序子问题。
最后,再将排序好的子数组合并为原始数组的有序序列。
在归并排序中,通过将问题划分为两个子问题,递归地排序子数组。
最后,再将排序好的子数组合并为原始数组的有序序列。
归并排序的特点是稳定性好,适用于大规模数据的排序。
2. 查找问题分治策略也可以应用于查找问题。
例如,在有序数组中查找某个元素可以使用二分查找算法,该算法也采用了分治思想。
二分查找算法通过将问题划分为两个子问题,然后根据子问题的规模逐步缩小查找范围,最终找到目标元素。
这种分治思想使得二分查找具有高效性。
3. 矩阵乘法矩阵乘法是一个常见的数学运算问题。
通过分治策略,可以将矩阵乘法划分为多个小问题,并递归地解决这些小问题。
然后,再将这些小问题的解进行合并,得到原始问题的解。
分治法用于矩阵乘法算法的优化,可以减少运算量,提高计算效率。
4. 搜索问题分治策略也可以应用于搜索问题。
例如,在搜索引擎中,分治策略可以用于并行搜索,从而加快搜索速度。
算法设计与分析:第02章 递归与分治策略
2.1
递归的概念
例4 排列问题 设计一个递归算法生成n个元素{r1,r2,…,rn}的全排列。 设R={r1,r2,…,rn}是要进行排列的n个元素,Ri=R-{ri}。 集合X中元素的全排列记为perm(X)。 (ri)perm(X)表示在全排列perm(X)的每一个排列前加上前 缀得到的排列。R的全排列可归纳定义如下: 当n=1时,perm(R)=(r),其中r是集合R中唯一的元素; 当n>1时,perm(R)由(r1)perm(R1),(r2)perm(R2),…, (rn)perm(Rn)构成。
分治法的基本步骤
divide-and-conquer(P) { if ( | P | <= n0) adhoc(P); //解决小规模的问题 divide P into smaller subinstances P1,P2,...,Pk;//分解问题 for (i=1,i<=k,i++) yi=divide-and-conquer(Pi); //递归的解各子问题 return merge(y1,...,yk); //将各子问题的解合并为原问题的解 } 人们从大量实践中发现,在用分治法设计算法时,最好使 子问题的规模大致相同。即将一个问题分成大小相等的k个子问 题的处理方法是行之有效的。这种使子问题规模大致相等的做 法是出自一种平衡(balancing)子问题的思想,它几乎总是比子 问题规模不等的做法要好。
1 5 n1 1 5 n1 1 F (n) 2 5 2
但本例中的Ackerman函数却无法找到非递归的定义。
2.1
例3 Ackerman函数
递归的概念
• A(n,m)的自变量m的每一个值都定义了一个单变量函数: • M=0时,A(n,0)=n+2 • M=1时,A(n,1)=A(A(n-1,1),0)=A(n-1,1)+2,和A(1,1)=2故 A(n,1)=2*n • M=2时,A(n,2)=A(A(n-1,2),1)=2A(n-1,2),和 A(1,2)=A(A(0,2),1)=A(1,1)=2,故A(n,2)= 2^n 。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
南京理工大学
Algorithm: MERGE(A, p, q, r) 输入:数组A[p...q]和A[q+1...r], 各自按升序排列 输出:将A[p...q]和A[q+1...r]合并成一个升序排序的新数组 1. i←p; j←q+1; k←p; 2. while i≤q and j≤r 3. if A[i] ≤A[j] then 4. B[k]←A[i] 5. i ←i+1 6. else 7. B[k]←A[j] 8. j←j+1 9. end if 10. k←k+1 11.end while 12. if i=q+1 then B[k...r] ←A[j...r] 13. else B[k...r] ←A[i...q] 14. end if 15. A ← B
// 设 2k=n
=2k-1C(2)+{2k-2} =2k-1+2k-2 =3n/2-2 (比简单直观的比较方法耗时少)
南京理工大学
关于n的讨论
• 当n≠2k时,则n可表为若干2的正整数幂之和 (e.g. 42=32+8+2), 若n是偶数,则算法的时间复杂度仍为 3n/2-2。 • e.g. 对n=42,将元素分为32个一组、8个一组和2个 一组共3组后, 各组找出最大、最小元素分别需要46、 10和1次比较, • 3个最大元素用2次比较即可得整体最大元素,同理 • 3个最小元素用2次比较即可得整体最小元素, • 故有46+10+1+2+2=61, • 而3n/2-2=3*42/2-2也等于61,故的确是3n/2-2。
1. 将其分分成左右两个子数组:
2. 对子数组进行排序(可采用任何排序方法) 。 3. 对排序后的子数组进行合并 :两个已排序的子数组用A[p…q]和A[q+1…r]表示. 设两个指针s和t,初始时各自指向A[p]和A[q+1],再设一空数组B[p…q, q+1…r] 做暂存器,比较元素A[s]和A[t], 将较小者添加到B , 然后移动指针, 若A[s]较小,则s+1,否则t+1, 直到s=q+1 或 t=r+1 为止 将剩余元素A[t…r] 或 A[s…q] 拷贝到数组B, 然后令A←B.
加 1, 即 n=2m1+2m2+ … +2mk+1 且 m1>m2> … >mk≥1, 由 于 2 +2 + … +2 =n-1, 故 i 1 (3ni / 2 2) =3(n-1)/2-2k,
m1 m2 mk
k
注意此时共有 k+1 组最大、最小元,取得整体解还需比较 2(k+1)-2 即 2k 次 (单独的一个元素既是该组最大元,也是该组最小元),故 全部的比较次数为 3(n-1)/2-2k + 2k=3(n-1)/2 即 3n/2-3/2,亦可看成 为 3n/2-2。
南京理工大学
当 n≠2k 但为偶数时,则可将 n 分解为若干 2 的正整数幂之和:
n=2m1+2m2+ … +2mk 且 m1>m2> … >mk≥1, 对规模为 ni=2mi 的每组元素,找出最大、最小元素需要 3ni/2-2 次比较, 故 获 得 k 组 各 自 的 最 大 、 最 小 元 的 时 间 复 杂 度 为
4 6 3 1 8 7 2 5
2 6 3 1 8 7 Φ5
2 Φ3 1 8 7 6 5 2 1 3 Φ8 7 6 5
2 1 3 4 8 7 6 5
南京理工大学
Algorithm: QUICKSORT(A[low…high]) 输入: n个元素的数组A[low…high] 输出:按非降序排列的数组A[low…high] 1. if low<high then 2. w ← SPLIT(A[low…high]) {w为基准元素A[low]的新位置} 3. quicksort(A, low, w-1) 4. quicksort(A, w+1, high) 5. end if
南京理工大学
将 A[1...8]={4, 6, 3, 1, 8, 7, 2, 5} 按照非降序方式 进行排序
• SPLIT:以待排序数组的首元素作为基准元素,将待排序数组 分成左右两个子数组。使得左边子数组中的元素都小于等于 基准元素;右边子数组中的元素都大于等于基准元素。 • 对左、右子数组进行相同的操作。
n 1
(a)-(b),并适当变换
C ( n) n1
C ( n1) n
2( n1) n( n1)
令D(n) C (n1) n
2( D(n) D(n 1) n( n1) , D(1) 0 n1)
D(n) 2 j 1 j (jj11) 2 j 1 ( j2 1) 2 j 1 1j
, n n0 c T ( n) aT (n / b) s(n) , n n0
• 回顾Master Theorem
南京理工大学
Master Theorem
设a≥1, b >1为常数, f(n)为一给定的函数, T(n)递归定义如下: T(n) =a· T(n/b) + f(n) 并且 T(n)有适当的初始值。那么,当 n 充分大时,有:
k i 1
(3ni / 2 2) =3n/2-2k,
然后 k 个最大元、k 个最小元分别各用 k-1 次比较就可求出整体的最 大元和最小元, 故全部的比较次数仍为(3n/2-2k) + (2k-2) = 3n/2-2。
南京理工大学
当 n≠2k 但为奇数时,则可将 n 分解为若干 2 的正整数幂之和
O(1) T (n) T (n 1) (n)
if n 1 if n 1
T (n) (n2 )
南京理工大学
平均情形: 我们用 C ( n) 表示对一个n个元素的数组进行快速排序所需要的总的比较次数。 1 2 … w … n
w-1 因此,我们有:
n-w
1 n w1 C (w 1) C (n w) n n n w1 C (n w) C (n 1) C (n 2) C (0) w1 C ( w 1) C (n) (n 1)
正规性条件的直观含义: 对所有足够大的n,a个子问题的分解准备与再组合所需要的时间总和,严格 小于原问题的分解准备和组合所需要的时间。
南京理工大学
快速排序
快速排序是一个非常流行而且高效的算法, 其平均时间复杂度为 Θ (nlogn). 其优于合并排序之处在于它在原位上排序,不需要额 外的辅助存贮空间(合并排序需Θ (n)的辅助空间)。Charles A. R. Hoare 1960 年发布了使他闻名于世的快速排序算法(Quicksort), 这个算法也是当前世界上使用最广泛的算法之一, 当时他供职于 伦敦一家不大的计算机生产厂家。1980 年,Hoare 被授予 Turing 奖,以表彰其在程序语言定义与设计领域的根本性的贡献。在 2000 年, Hoare 因其在计算机科学和教育方面的杰出贡献被英国 皇家封为爵士。
南京理工大学
使用分治策略的算法的时间复杂度分析
• 从分治法的一般设计模式可以看出,用它设计出的算 法通常可以是递归算法。因而,算法的效率通常可以 用递归方程来分析。 • 假设算法将规模为n的问题分解为a(a>=1)个规模为 n/b(b>1)的子问题解决。分解子问题以及合并子问题 的解耗费的时间为s(n),则算法的时间复杂度可以递 归表示为:
2 n C (n) (n 1) w1 C ( w 1) n
南京理工大学
n C (n) n(n 1) 2 w1 C ( w 1) (a)
n
n-1替换n
(n 1)C (n 1) (n 1)(n 2) 2 w1 C ( w 1) (b)
南京理工大学
算法MINMAX
输入:n 个元素的数组 A[1…n], n 为 2 的整数 k 次幂 输入:A[1…n]的最大最小元素 MINMAX(low, high) 1. if high-low=1 2. return (min(A[low],A[high]), max(A[low],A[high])) 3. else 4. mid = (low+high)/2 5. (x1,y1) ← minmax(low, mid) {Devide} 6. (x2,y2) ← minmax(mid+1, high) {Devide} 7. x ← min(x1,x2) {Combine} 8. y ← max(y1,y2) {Combine} 9. return (x, y) 10. end if
南京理工大学
分治策略的思想
• 把规模较大的问题分解为若干个规模较小的子问题, 这些子问题相互独立且与原问题同类; (该子问题的 规模减小到一定的程度就可以容易地解决) • 依次求出这些子问题的解,然后把这些子问题的解组 合起来得到原问题的解。 • 由于子问题与原问题是同类的,故分治法可以很自然地 应用递归。
南京理工大学
使用分治策略的算法设计模式
divide_and_conquer(P) { if(|P|<=n0) direct_process(P); else { divide P into smaller subinstances P1,P2,…,Pa for(int i=1;i<=a;i++) yi=divide_and_conquer(Pi); merge(y1,y2,…,ya); } }
南京理工大学
复杂度分析
元素比较次数
if n 2 1 C (n) 2C (n / 2) 2 if n 2