栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

第二章-2.3-分析算法(分治法及其分析、归并排序)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

第二章-2.3-分析算法(分治法及其分析、归并排序)

一、分治法(The divide-and-conquer approach) 1、分治模式的三个步骤:

(1)分解原问题为若干个子问题。归并排序中将n个元素分解为n/2个元素。

(2)解决这些子问题,递归求解各个子问题。在归并排序中是递归排序两个子序列。

(3)合并这些子问题的解从而形成原问题的解。在归并排序中将两个已排序的子序列合并产生一个已排序的答案。

2、归并排序(merge sort)具体分析: (1)关键

关键在于“合并”两个已经排序好的子序列。

(2)引入辅助过程和两个子数组

引入一个辅助过程MERGE(A,p,q,r),其中p、q、r均为下标,满足p<=q (3)如何理解归并排序?

 以分排试卷为例,目标是将两叠排序好的试卷堆A(1009890)和B(999592)合并成C堆,第一步比较最下面的试卷,抽出更大的(第一步是抽出100分的卷子)给C堆,后面几步都和第一步一样,从而最终的C堆就是从高到低排出来的六张试卷。

 (4)编排伪代码

此时引入空白卷(0分),0分放在的是两堆卷子的最上面,当0分显露的时候,这不可能是更低的卷子,除非两张0分都露了出来,但是这种情况的发生意味着所有卷子已经排好。

我们设A堆为A[1...3],B堆为A[4...6],即p = 1,q = 3, r = 6,后面验证伪代码的时候可以将这些数字代入进去。

给出我们的伪代码:

MERGE(A,p,q,r)
//写出n1和n2的数量
n1 = q - p + 1
n2 = r - q
//让两个数组合并成一个数组
Let L[1..n1+1] and R[1..n2+1] be new arrays
//分别将A中两个子序列赋值给数组L和R
for i = 1 to n1
    L[i] = A[p + i - 1]        //从A的第p位开始赋值
for j = 1 to n2
    L[j] = A[q + j]            //从A的第q+1位开始赋值
//引入两张零分试卷
L[n1+1] = 0
R[n2+2] = 0
i = 1
j = 1
//比较各自最大的试卷,抽出更大的
for k = p to r
    if L[i] >= R[j]    
        A[k] = L[i]
        i = i + 1
    else A[k] = R[j]
        j = j + 1
 (5)理解MERGE的运行时间

【1】两个for循环以外部分都是常量时间

【2】第一个for循环需要Θ(n1+n2)=Θ(n),其中n = r - p + 1

【3】第二个for循环迭代n次,每次迭代均需要常量时间

因此其运行时间为Θ(n)

(6)将MERGE作为归并排序的子程序

【1】数学知识铺垫

 【2】下面通过MERGE-SORT来排序子数组中A[p...r]中的元素:当p >= r,子数组最多有一个元素,所以已经排序完成;当p < r,将A分成两个子数组A[p...q]和A[q+1...r],然后通过伪代码完成对子数组的排序。

【3】为了排序整个序列A = ,我们调用MERGE-SORT(A,1,A.length),其中A.length=2ⁿ ,这就形成了一个递归结构,返回时先将两个1项子数组的合并成2项的子数组,再将两个2项子数组的合并成一个4项的子数组,依此类推...下图为A=<5,2,4,7,1,3,2,6>里归并排序的操作。

二、分析分治算法 1、引入

假设T(n)为规模为n的一个问题的运行时间。

①问题规模足够小的时候,比如n<=常量c,那么直接求解需要常量的时间,此时运行时间为Θ(1)。

②问题规模大的时候,将原问题分解为a个子问题,得每个子问题规模为原来的1/b(在归并排序中a=b,但是往往a!=b),因此我们需要aT(n/b)时间来解决这些子问题。假设分解成子问题需要时间D(n),合并子问题解成原问题需要C(n),因此得到下图式子

2、归并排序算法分析

(1)分解:分解步骤仅需计算子数组的中间位置,需要常量时间,因此D(n) = Θ(1)

解决:递归求解两个规模均为n/2的子问题,将贡献2T(n/2)的运行时间

合并:上面的MERGE运行时间为Θ(n),那么C(n) = Θ(n)

(2)C(n) + D(n) = Θ(n),因为两者相加本质上是一个线性函数,因此与解决的步骤相加,得

 事实上T(n)为Θ(lgn),lgn代表

下面来理解这个原理,先将T(n)改写为

 下图为递归树

 解释:

【1】顶层的代价为cn,在后面几幅图中被扩展为递归树,第二层的代价为cn/2,第三层为cn/4(结合T(n)的表达式可以看出)...一直到问题规模下降到1,即代价为c。

【2】我们可以发现这时候的树高为lgn(即log2 (n)),有lgn+1层,每层代价为cn,因此Total = (lgn + 1) * cn = cn lgn + cn,因此忽略低阶项和常数后结果为

Θ(nlgn)

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1019677.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号