《算法设计与分析》第05章
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
南京邮电大学计算机学院 2008年3月 2008年
5.1.2 算法分析
采用分治法求解问题通常得到一个递归算法。 采用分治法求解问题通常得到一个递归算法。如 果较大的问题被分解成同样大小的几部分, 果较大的问题被分解成同样大小的几部分,那么分 析相应算法的执行时间,往往可得到如下的递推关 析相应算法的执行时间, 系式: 系式: T(n) = aT(n/b) + cnk,T(1) = c
南京邮电大学计算机学院 2008年3月 2008年
【程序5-1】 分治法 程序5 SolutionType DandC(ProblemType P) { ProblemType P1,P2,L,Pk; if (Small(P)) return S(P); else { Divide(P,P1,P2,L,Pk); , Return Combine(DandC(P1), , DandC(P2),…,DandC(Pk)); , , } }
南京邮电大学计算机学院 2008年3月 2008年
定理5 定理5-3 对于n≥ , 程序5- 的对半搜索递归函数 对于 ≥0, 程序 - 7的对半搜索递归函数 BSearch是正确的。 是正确的。 是正确的
程序5-7是尾递归函数, 程序 是尾递归函数,易改为迭代形式 是尾递归函数 参考程序5-8 参考程序
5.2.1 分治法求解
【程序5-4】 求最大最小元 程序5 template <class T> void SortableList<T>::MaxMin(T& max, T& min)const { if (n==0)return; max=min=l[0]; for (int i=1; i<n; i++) { if(l[i]>max) max=l[i]; if(l[i]<min) min=l[i]; } } 时间复杂度? 时间复杂度?
i =0 m
= ca
m
( bk / a )i ∑
i =0
m
南京邮电大学计算机学院 2008年3月 2008年
设r= bk /a ,下面分三种情况计算 。 (1)若r<1,则 m r i 1 /( 1 r ) ) , ∑ < −
i =0
所以 T(n) =Θ(n ) m (2)若r=1,则 ∑r i = 1 + m = 1 + logb n ) ,
南京邮电大学计算机学院 2008年3月 2008年
定理5 定理5-1 设a,b,c和k为常数,T(n)=aT(n/b)+cnk, 为常数, 和 为常数 T(1)=c,则, ,
Θ( nlogb a ) T( n ) = Θ( nk log n ) Θ( nk )
a 如果 > b
南京邮电大学计算机学院 2008年3月 2008年
//程序 //程序5-8:对半搜索的迭代算法 程序5 template <class T> int SortableList<T>::BSearch1(const T& x)const { int m, left=0, right=n-1; right=nwhile (left<=right){ m=(left+right)/2; if (x<l[m]) right=m-1; right=melse if (x>l[m]) left=m+1; else return m; //搜索成功 //搜索成功 } returnreturn-1; //搜索失败 //搜索失败 }
南京邮电大学计算机学院 2008年3月 2008年
【程序5-5】分治法求最大最小元 程序5 template <class T> void SortableList<T>::MaxMin(int i, int j, T& max, T& min) const { T min1,max1; if (i==j) max=min=l[i]; else if (i==j-1) //只有两个元素时 只有两个元素时 if (l[i]<l[j]) { max=l[j]; min=l[i]; } else { max=l[i]; min=l[j]; }
南京邮电大学计算机学院 2008年3月 2008年
【程序5-6】二分搜索算法框架 程序5 template <class T> int SortableList<T>::BSearch(const T& x, int left,int right)const { if (left<=right){ int m=Divide(left+right); if (x<l[m]) return BSearch(x,left,m-1); else if (x>l[m]) return BSearch(x,m+1,right); else return m; } return -1; }
5.1 分治法的基本思想 5.2 求最大最小元 5.3 二分搜索 5.4 排序问题 5.5 选择问题 5.6 斯特拉森矩阵乘法
南京邮电大学计算机学院 2008年3月 2008年
5.1 一般方法
南京邮电大学计算机学院 2008年3月 2008年
5.1.1 分治法的基本思想
分治法顾名思义就是分而治之 。 分治法 顾名思义就是分而治之。 一个问题能够 顾名思义就是分而治之 用分治法求解的要素是:第一, 用分治法求解的要素是:第一,问题能够按照某 种方式分解成若干个规模较小、 种方式分解成若干个规模较小、相互独立且与原 问题类型相同的子问题;第二, 问题类型相同的子问题;第二,子问题足够小时 可以直接求解;第三, 可以直接求解;第三,能够将子问题的解组合成 原问题的解。由于分治法要求分解成同类子问题, 原问题的解。由于分治法要求分解成同类子问题, 并允许不断分解,使问题规模逐步减小, 并允许不断分解,使问题规模逐步减小,最终可 用已知的方法求解足够小的问题,因此, 用已知的方法求解足够小的问题,因此,分治法 求解很自然导致一个递归算法。 求解很自然导致一个递归算法。
南京邮电大学计算机学院 2008年3月 2008年
5.3.1 分治法求解
int SortableList<T>::BSearch(const T& x, int left,int right)const 的表中搜索与x有相同关键 说明: 在范围为 说明: 在范围为[left,right]的表中搜索与 有相同关键 的表中搜索与 字值的元素;如果存在该元素, 字值的元素;如果存在该元素,则函数返回该元素 在表中的位置,否则函数返回- ,表示搜索失败。 在表中的位置,否则函数返回-1,表示搜索失败。
5.1.3 排序问题 数据结构
【程序5-3】 可排序表类 程序5 template <class K,class D> struct E { //可排序表中元素的类型 可排序表中元素的类型 operator K( )const { return key;} K key; D data; };
南京邮电大学计算机学院 2008年3月 2008年
南京邮电大学计算机学院 2008年3月 2008年
【程序5-2】 一分为二的分治法 程序5 SolutionType DandC(int left,int right) , { if (Small(left, right)) return S(left,right); else { int m=Divide(left,right); , Return Combine(DandC(left,m), , , DandC(m+1,right)); , } }
“十一五”国家级规划教 十一五” 材
电子工业出版社
算法设计与分析
DeSign and Analysis of Algorithms In C++
陈慧南 编著
南京邮电大学计算机学院 2008年3月 2008年
第2部分 算法设计策略
南京邮电大学计算机学院 2008年3月 2008年
第5章 分治法
南京邮电大学计算机学院 2008年3月 2008年
南京邮电大学计算机学院 2008年3月 2008年
else { int m=(i+j)/2; MaxMin(i,m,max,min); MaxMin(m+1,j,max1,min1); if (max<max1) max=max1; if (min>min1) min=min1; } }
南京邮电大学计算机学院 2008年3月 2008年
南京邮电大学计算机学院 2008年3月 2008年
5.2 求最大最小元
南京邮电大学计算机学院 2008年3月 2008年
问题 在一个元素集合L中寻找最大元素和最小元 在一个元素集合 中寻找最大元素和最小元 素的问题。 素的问题。 一般方法? 一般方法?
南京邮电大学计算机学院 2008年3月 2008年
n> 2
设n=2k,易解
南京邮电大学计算机学院 2008年3月 2008年
5.3 二分搜索
南京邮电大学计算机学院 2008年3月 2008年
问题 在有序表(已按关键字值非减排序) 在有序表(已按关键字值非减排序)中搜 索给定元素的问题。 索给定元素的问题。
a0 a0
…
am-1 am am+1
…
an-2 an-1
k
如果 = bk a a 如果 < bk
南京邮电大学计算机学院 2008年3月 2008年
n=bm
T( n ) = aT( n / b ) + cnk = a( aT( n / b2 ) + c( n / b )k ) + cnk M = amT( 1 ) + am−1c( n / bm−1 )k +L+ ac( n / b )k + cnk = c∑am−i bik
南京邮电大学计算机学院 2008年3月 2008年
5.3.3 二叉判定树
二分搜索过程的算法行为可以用一棵二叉树来 描述。 描述。通常称这棵描述搜索算法执行过程的二叉 二叉判定树(binary tree)。 树为二叉判定树 树为二叉判定树(binary decision tree)。
template <class T> class SortableList { //可排序表类 可排序表类 public: SortableList(int mSize); ~SortableList(); M private: M T *l ; //指向动态生成的一位数组 指向动态生成的一位数组 int maxSize; int n; };
5.2.2 时间分析
定理5 定理5-2
设有n个元素的表,假定n是 的幂 的幂, 设有 个元素的表,假定 是2的幂,即n=2k,k 个元素的表 在最好、 是正整数,程序5-5在最好 是正整数,程序5-5在最好、平均和最坏情况下 的比较次数都为3n/2–2。 的比较次数都为 。
n=1 0 T( n ) = 1 n= 2 T( n / 2 ) + T( n / 2 ) + 2
logb a
i= i =0
所以 T(n) =Θ(n log n ) =Θ( nk log n ) m+1 −1 (3)若r>1,则 m i r ) , r = =Θ( r m ) ∑ r −1 i =0
logb a
所以 T(n) =Θ(amr m ) =Θ( bk⋅m ) =Θ( nk )
南京邮电大学计算机学院 2008年3月 2008年
南京邮电大学计算机学院 2008年3月 2008年
5.3.2 对半搜索
对半搜索 对半搜索是一种二分搜索。 对半搜索是一种二分搜索。设当前搜索的子表 为(aleft,aleft+1,…,aright), 令 m=(left+right)/2
南京邮电大学计算机学院 2008年3月 2008年
Fra Baidu bibliotek
【程序5-7】 对半搜索递归算法 程序5 template <class T> int SortableList<T>::BSearch(const T& x, int left, int right)const { if (left<=right){ int m=(left+right)/2; if (x<l[m]) return BSearch(x,left,m-1); else if (x>l[m]) return BSearch(x,m+1,right); else return m; } return -1; }
5.1.2 算法分析
采用分治法求解问题通常得到一个递归算法。 采用分治法求解问题通常得到一个递归算法。如 果较大的问题被分解成同样大小的几部分, 果较大的问题被分解成同样大小的几部分,那么分 析相应算法的执行时间,往往可得到如下的递推关 析相应算法的执行时间, 系式: 系式: T(n) = aT(n/b) + cnk,T(1) = c
南京邮电大学计算机学院 2008年3月 2008年
【程序5-1】 分治法 程序5 SolutionType DandC(ProblemType P) { ProblemType P1,P2,L,Pk; if (Small(P)) return S(P); else { Divide(P,P1,P2,L,Pk); , Return Combine(DandC(P1), , DandC(P2),…,DandC(Pk)); , , } }
南京邮电大学计算机学院 2008年3月 2008年
定理5 定理5-3 对于n≥ , 程序5- 的对半搜索递归函数 对于 ≥0, 程序 - 7的对半搜索递归函数 BSearch是正确的。 是正确的。 是正确的
程序5-7是尾递归函数, 程序 是尾递归函数,易改为迭代形式 是尾递归函数 参考程序5-8 参考程序
5.2.1 分治法求解
【程序5-4】 求最大最小元 程序5 template <class T> void SortableList<T>::MaxMin(T& max, T& min)const { if (n==0)return; max=min=l[0]; for (int i=1; i<n; i++) { if(l[i]>max) max=l[i]; if(l[i]<min) min=l[i]; } } 时间复杂度? 时间复杂度?
i =0 m
= ca
m
( bk / a )i ∑
i =0
m
南京邮电大学计算机学院 2008年3月 2008年
设r= bk /a ,下面分三种情况计算 。 (1)若r<1,则 m r i 1 /( 1 r ) ) , ∑ < −
i =0
所以 T(n) =Θ(n ) m (2)若r=1,则 ∑r i = 1 + m = 1 + logb n ) ,
南京邮电大学计算机学院 2008年3月 2008年
定理5 定理5-1 设a,b,c和k为常数,T(n)=aT(n/b)+cnk, 为常数, 和 为常数 T(1)=c,则, ,
Θ( nlogb a ) T( n ) = Θ( nk log n ) Θ( nk )
a 如果 > b
南京邮电大学计算机学院 2008年3月 2008年
//程序 //程序5-8:对半搜索的迭代算法 程序5 template <class T> int SortableList<T>::BSearch1(const T& x)const { int m, left=0, right=n-1; right=nwhile (left<=right){ m=(left+right)/2; if (x<l[m]) right=m-1; right=melse if (x>l[m]) left=m+1; else return m; //搜索成功 //搜索成功 } returnreturn-1; //搜索失败 //搜索失败 }
南京邮电大学计算机学院 2008年3月 2008年
【程序5-5】分治法求最大最小元 程序5 template <class T> void SortableList<T>::MaxMin(int i, int j, T& max, T& min) const { T min1,max1; if (i==j) max=min=l[i]; else if (i==j-1) //只有两个元素时 只有两个元素时 if (l[i]<l[j]) { max=l[j]; min=l[i]; } else { max=l[i]; min=l[j]; }
南京邮电大学计算机学院 2008年3月 2008年
【程序5-6】二分搜索算法框架 程序5 template <class T> int SortableList<T>::BSearch(const T& x, int left,int right)const { if (left<=right){ int m=Divide(left+right); if (x<l[m]) return BSearch(x,left,m-1); else if (x>l[m]) return BSearch(x,m+1,right); else return m; } return -1; }
5.1 分治法的基本思想 5.2 求最大最小元 5.3 二分搜索 5.4 排序问题 5.5 选择问题 5.6 斯特拉森矩阵乘法
南京邮电大学计算机学院 2008年3月 2008年
5.1 一般方法
南京邮电大学计算机学院 2008年3月 2008年
5.1.1 分治法的基本思想
分治法顾名思义就是分而治之 。 分治法 顾名思义就是分而治之。 一个问题能够 顾名思义就是分而治之 用分治法求解的要素是:第一, 用分治法求解的要素是:第一,问题能够按照某 种方式分解成若干个规模较小、 种方式分解成若干个规模较小、相互独立且与原 问题类型相同的子问题;第二, 问题类型相同的子问题;第二,子问题足够小时 可以直接求解;第三, 可以直接求解;第三,能够将子问题的解组合成 原问题的解。由于分治法要求分解成同类子问题, 原问题的解。由于分治法要求分解成同类子问题, 并允许不断分解,使问题规模逐步减小, 并允许不断分解,使问题规模逐步减小,最终可 用已知的方法求解足够小的问题,因此, 用已知的方法求解足够小的问题,因此,分治法 求解很自然导致一个递归算法。 求解很自然导致一个递归算法。
南京邮电大学计算机学院 2008年3月 2008年
5.3.1 分治法求解
int SortableList<T>::BSearch(const T& x, int left,int right)const 的表中搜索与x有相同关键 说明: 在范围为 说明: 在范围为[left,right]的表中搜索与 有相同关键 的表中搜索与 字值的元素;如果存在该元素, 字值的元素;如果存在该元素,则函数返回该元素 在表中的位置,否则函数返回- ,表示搜索失败。 在表中的位置,否则函数返回-1,表示搜索失败。
5.1.3 排序问题 数据结构
【程序5-3】 可排序表类 程序5 template <class K,class D> struct E { //可排序表中元素的类型 可排序表中元素的类型 operator K( )const { return key;} K key; D data; };
南京邮电大学计算机学院 2008年3月 2008年
南京邮电大学计算机学院 2008年3月 2008年
【程序5-2】 一分为二的分治法 程序5 SolutionType DandC(int left,int right) , { if (Small(left, right)) return S(left,right); else { int m=Divide(left,right); , Return Combine(DandC(left,m), , , DandC(m+1,right)); , } }
“十一五”国家级规划教 十一五” 材
电子工业出版社
算法设计与分析
DeSign and Analysis of Algorithms In C++
陈慧南 编著
南京邮电大学计算机学院 2008年3月 2008年
第2部分 算法设计策略
南京邮电大学计算机学院 2008年3月 2008年
第5章 分治法
南京邮电大学计算机学院 2008年3月 2008年
南京邮电大学计算机学院 2008年3月 2008年
else { int m=(i+j)/2; MaxMin(i,m,max,min); MaxMin(m+1,j,max1,min1); if (max<max1) max=max1; if (min>min1) min=min1; } }
南京邮电大学计算机学院 2008年3月 2008年
南京邮电大学计算机学院 2008年3月 2008年
5.2 求最大最小元
南京邮电大学计算机学院 2008年3月 2008年
问题 在一个元素集合L中寻找最大元素和最小元 在一个元素集合 中寻找最大元素和最小元 素的问题。 素的问题。 一般方法? 一般方法?
南京邮电大学计算机学院 2008年3月 2008年
n> 2
设n=2k,易解
南京邮电大学计算机学院 2008年3月 2008年
5.3 二分搜索
南京邮电大学计算机学院 2008年3月 2008年
问题 在有序表(已按关键字值非减排序) 在有序表(已按关键字值非减排序)中搜 索给定元素的问题。 索给定元素的问题。
a0 a0
…
am-1 am am+1
…
an-2 an-1
k
如果 = bk a a 如果 < bk
南京邮电大学计算机学院 2008年3月 2008年
n=bm
T( n ) = aT( n / b ) + cnk = a( aT( n / b2 ) + c( n / b )k ) + cnk M = amT( 1 ) + am−1c( n / bm−1 )k +L+ ac( n / b )k + cnk = c∑am−i bik
南京邮电大学计算机学院 2008年3月 2008年
5.3.3 二叉判定树
二分搜索过程的算法行为可以用一棵二叉树来 描述。 描述。通常称这棵描述搜索算法执行过程的二叉 二叉判定树(binary tree)。 树为二叉判定树 树为二叉判定树(binary decision tree)。
template <class T> class SortableList { //可排序表类 可排序表类 public: SortableList(int mSize); ~SortableList(); M private: M T *l ; //指向动态生成的一位数组 指向动态生成的一位数组 int maxSize; int n; };
5.2.2 时间分析
定理5 定理5-2
设有n个元素的表,假定n是 的幂 的幂, 设有 个元素的表,假定 是2的幂,即n=2k,k 个元素的表 在最好、 是正整数,程序5-5在最好 是正整数,程序5-5在最好、平均和最坏情况下 的比较次数都为3n/2–2。 的比较次数都为 。
n=1 0 T( n ) = 1 n= 2 T( n / 2 ) + T( n / 2 ) + 2
logb a
i= i =0
所以 T(n) =Θ(n log n ) =Θ( nk log n ) m+1 −1 (3)若r>1,则 m i r ) , r = =Θ( r m ) ∑ r −1 i =0
logb a
所以 T(n) =Θ(amr m ) =Θ( bk⋅m ) =Θ( nk )
南京邮电大学计算机学院 2008年3月 2008年
南京邮电大学计算机学院 2008年3月 2008年
5.3.2 对半搜索
对半搜索 对半搜索是一种二分搜索。 对半搜索是一种二分搜索。设当前搜索的子表 为(aleft,aleft+1,…,aright), 令 m=(left+right)/2
南京邮电大学计算机学院 2008年3月 2008年
Fra Baidu bibliotek
【程序5-7】 对半搜索递归算法 程序5 template <class T> int SortableList<T>::BSearch(const T& x, int left, int right)const { if (left<=right){ int m=(left+right)/2; if (x<l[m]) return BSearch(x,left,m-1); else if (x>l[m]) return BSearch(x,m+1,right); else return m; } return -1; }