您的位置:首页 > 编程语言 > C语言/C++

《算法导论》读书笔记(二)——分治法

2013-09-02 22:15 141 查看

设计算法

插入排序使用了增量法,即先排j-1个,然后排j个,下面学习一种新的方法:分治法。

分治法

分治法的思想:大事化小,分而治之。把规模较大的问题分解为几个规模较小的类似子问题,递归的求解子问题,然后合并子问题的解建立原问题的解。

递归:算法多次调用自身以解决紧密相关的若干子问题。

分治模式在每次递归的三个步骤:

分解:大→小

解决:对子问题递归,若子问题足够小,直接求解

合并:小→大

分治法应用于排序:归并排序

分解:将n元素序列分解为2个n/2元素子序列

解决:递归解两个子序列

合并:合并两个子序列产生答案

归并排序的C++简单实现:

#include <iostream>
using namespace std;

template <typename T>
void merge(T a[], int p, int q, int r)
{
int temp_N = r - p + 1;
int p_i = p;
int p_j = q + 1;
int p_t = 0;
T temp_Array[temp_N];
while(p_i < q + 1 && p_j < r + 1)
{
if(a[p_i] < a[p_j])
{
temp_Array[p_t] = a[p_i];
p_i++;
p_t++;
}
else
{
temp_Array[p_t] = a[p_j];
p_j++;
p_t++;
}
}
while(p_i < q + 1)
{
temp_Array[p_t] = a[p_i];
p_i++;
p_t++;
}
while(p_j < r + 1)
{
temp_Array[p_t] = a[p_j];
p_j++;
p_t++;
}

for(int i = 0; i < temp_N; i++)
{
a[p + i] = temp_Array[i];
}
}

template <typename T>
void merge_Sort(T a[], int p, int r)
{
if(p < r)
{
int q = (r + p) / 2;
merge_Sort(a, p, q);
merge_Sort(a, q + 1, r);
merge(a, p, q, r);
}

}

int main()
{
int a[10] = {1,5,3,18,2,4,16,9,101,11};
merge_Sort(a,0,9);
for(int i = 0; i < 10; i++)
{
cout << a[i] << "\t";
}
cout << endl;
return 0;
}


归并算法示意图



分治算法分析

递归算法通常通过递归方程来求解运行时间

递归方程如下:

当n足够小时,即n < c时有:T(n) = Θ(1)

其他情况:T(n) = aT(n/b) + D(n) + C(n).

对于其他情况的解释:

a:分成a份

b:每份的求解时间是1/b

D(n):分解所需时间

C(n):合并所需时间

分析归并排序

用如上方法得出:

a=2

b=2

D(n)=Θ(1)

C(n)=Θ(n)

应用“主定理”有:归并排序的时间复杂度是T(n) = Θ(nlogn)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法导论 C++