计算机算法设计与分析观后小总结

本文是对《计算机算法设计与分析》的初步总结,重点关注递归与分治策略以及动态规划。文章阐述了递归的定义,以二分搜索和快速排序为例说明分治策略的应用,并探讨了动态规划的最优子结构和重叠子问题特性,通过0-1背包问题解释了动态规划的解题思路。同时,提到了贪心算法在找硬币问题中的应用,以及贪心算法与动态规划的区别。
摘要由CSDN通过智能技术生成

简单略看了一遍王晓东的《计算机算法设计与分析》,很多地方没有细看,现在先做个小总结,方便以后回头看的时候记忆起一些内容。

第二章:递归与分治策略

递归的概念:

直接或间接地调用自身的算法称为递归算法。用函数自身给出定义的函数称为递归函数。

分治法的基本思想:

分治法的基本思想是将一个规模为n的问题分解为k个规模较小的子问题,这些子问题互相独立且与原问题相同。递归地解这些子问题,然后将各子问题的解合并得到原问题的解。它的一般的算法设计模式如下:

divide-and-conquer(P){
if(|P|<=n0)
adhoc(P);
divide P into smaller subinstances P1,P2,...,Pk;
for(i =1;i<=k;i++)
yi=divide-and-conquer(Pi);
return merge(y1,y2,...,yk);
}
其中,|P|表示问题P的规模,n0为一个阈值,表示当问题P的规模不超过n0时,问题已容易解出,不必再继续分解。adhoc(P)是该分治法中的基本子算法,用于直接解小规模的问题P。当P的规模不超过n0时,直接用算法adhoc(P)求解。算法merge(y1,y2,...,yk)是该分治法中的合并子算法,用于将P的子问题P1,P2,...,PK的解y1,y2,...,yk合并为P的解。

人们从大量实践中发现,在用分治法设计算法时,最好使子问题的规模大致相同。即将一个问题分成大小相等的K个子问题的处理方法是行之有效的。许多问题可以取K=2。

然后是递归分治的一些应用例子:

(1)二分搜索技术

若是给定n个排好序的元素。

假设现在要搜索x,对于存放在数组,每次先取a[n/2]与x比较。如果x=a[n/2],则找到x,算法终止;如果x<a[n/2],则只继续在[0,n/2-1]区间搜索;x>a[n/2]则在[n/2+1,n-1]搜索。很明显这个搜索过程与搜索BFS(二叉搜索树)类似。

(2)合并排序

基本思想:若要对n个元素进行排序(按增序排序,即从小到大),那么在n不等于1的时候(n>1),把n个元素分成大小相等的两份,分别对这两个子部分进行排序,然后对这两个子部分进行合并。当n=1的时候,明显不用再分了,只需要合并即可。主要的排序其实是发生在合并过程中。

算法大概这样:先说说合并,合并过程如下:给两个变量i、j,他们分别指向两个子部分a[n/2]、b[n/2]的起始元素,(这里就让i、j作为下标)。比如i=k时,a[i]代表是数组a中第k+1个元素。不断比较a[i]和b[j],小的那个放入临时数组temp[n],然后小的那个元素对应的变量往后移一位,如i++或j++,直至i=n/2或j=n/2。之后就把剩下没放进数组temp的元素按原来的顺序依次放进去即可。这个合并过程就是最后一趟合并,很明显如果想要这趟合并之后的temp数组就是排好序的数组的话,a[n/2]和b[/n]必须是排好序的。为了对这两个数组排序,可以将a[n/2]和b[n/2]再各自分解成规模相等的两个子数组c[n/4]、d[n/4]和e[n/4]、f[n/4],再分别合并。只有当n=1时,才可以直接合并,否则都是先分成更小的两个部分。所以就有了先分治。

下面给出简单实现代码:

void MergeSort(int *a,const int left,const int right){//合并排序,a是要排序的数组地址,left和right是要进行排序的范围
	if (left >= right)
		return;
	int p = (left + right) / 2;
	MergeSort(a, left, p);
	MergeSort(a, p + 1, right);
	Merge(a, left, right, p);
}
void Merge(int *a,const int left,const int right,const int p){//合并两个子数组
	int i = left, j = p + 1;//他们各自的其实位置由left和p给出.用i、j作为他们各自的下标
	int *temp = new int[right - left + 1](), m = 0;//开辟临时数组temp,m作为它的下标
	while ((i < p + 1) &&
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值