《算法导论》读书笔记(二)——分治法
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)
相关文章推荐
- 《算法导论》读书笔记之图论算法—Dijkstra 算法求最短路径
- 算法导论第三版第四章 最大子数组和的三种解法(暴力、教材分治法、线性解法)
- 算法导论学习2.3 分治法 (这个递归终于懂了。。)
- 《算法导论》读书笔记(三)——分治策略之和最大连续子序列
- 《算法导论(原书第2版)》读书笔记
- 《算法导论》读书笔记(七)
- 算法导论—读书笔记2010.12.6
- 《算法导论》读书笔记之第6章 堆排序
- 算法导论第2章(4) 分治法的应用 找逆序对 (习题2-4)
- 算法导论-分治法-最近点对-HDOJ1007
- 《算法导论》读书笔记之第15章 动态规划[总结]
- 算法导论第三版第四章 最大子数组和的三种解法(暴力、教材分治法、线性解法)
- 《算法导论》读书笔记--第四章 分治策略
- 读书笔记:《算法导论》,写在前面
- 《算法导论》读书笔记(一)
- 《算法导论》读书笔记之第14章 数据结构的扩张
- 【CLRS】《算法导论》读书笔记(三):计数排序(Counting sort)、基数排序(Radix sort)和桶排序(Bucket sort)
- 读书笔记——《算法导论》第一章
- 《算法导论》读书笔记之第16章 0-1背包问题—动态规划求解
- 算法导论第三版第四章 最大子数组和的三种解法(暴力、教材分治法、线性解法)