码迷,mamicode.com
首页 > 编程语言 > 详细

《算法导论》读书笔记--第二章 2.3 设计算法

时间:2015-07-17 14:01:15      阅读:129      评论:0      收藏:0      [点我收藏+]

标签:

我们可以使用的算法设计技术有很多。插入排序用的是增量方法,即在已经排好的数组中不断加入新的元素。下面考虑一种被称为“分治法”的设计方法。

2.3.1分治法

分治法的思想:将原问题分解为几个规模较小但是类似于原问题的子问题,递归地求解这些子问题,然后合并这些子问题的解来建立原问题的解。分治模式在每层递归时有三个步骤:

分解原问题为若干子问题;

解决这些子问题,递归地求解各子问题,若子问题规模足够小,则直接求解;

合并这些子问题的解成原问题的解。

归并排序算法完全遵循分治模式,操作如下:

分解:分解待排序的n个元素的序列成各具n/2个元素的两个子序列;

解决:使用归并排序递归地排序两个子序列;

合并:合并已经排序的子序列以产生已排序的答案。

当被排序的序列长度为1时,递归“开始回升”。

下面写出合并这一步的伪代码,时间复杂度为theta(n).

//MERGE  伪代码
n1 = q - p + 1
n2 = r - q 
Let L[1..n1+1] and R[1..n2+1] be new arrays
for i = 1 to n1
    L[i] = A[p + i -1]
for j = 1 to n2
    R[i] = A[q+j]
L[n1 + 1] = ∞
R[n2 + 1] = ∞
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

注意点:

1、从左右两个序列中依次取出最小的数存入原数组中;

2、左右两个子序列分别递增,在哪一个子列选出一个数,这个序列下标加1;

3、为了不用每次确认子序列是否为空,要在子序列的最后放一张“哨兵牌”,这张牌非常大,当碰到这张牌时,一定是另一个序列的数被选出,当两个子序列都到达“哨兵牌”时,此时恰好所有数都存进原数组了(由循环头的迭代数目控制);在左右序列的长度不一致时,哨兵牌才会发挥威力,两个子序列长度一样的时候,同时达到最后一张牌,那么“哨兵牌”就没什么作用了;

4、另外注意的是,需要开辟新的数组来存储每个子序列,注意下标的确认,尤其是计算子序列长度时不要弄错。

 

 

 

《算法导论》读书笔记--第二章 2.3 设计算法

标签:

原文地址:http://www.cnblogs.com/batteryhp/p/4654070.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!