题型,逐一击破)"/>
计算机算法与设计复习4(各类题型,逐一击破)
一、着色问题
- 题目:求解图着色问题。给定无向连通图G如下圈所示,给定顾色种类数为m。用这些颜色为图G的各顶点着色,每个顶点着一种颜色。如果有一种着色法使G中每条边的两个顶点着不同颜色,则称这个图是可着色的。图的m着色问题是对于给定图G和m种颜色,假设m=3,找出所有不同的着色法。请用回溯法给出所有着色方案(请用1,2,3分别表示3种不同的颜色)
1. 蛮力法(穷举法)
n=4, k=4, m=3,其着色方案有12个。
第1个着色方案:1 2 2 3
第2个着色方案:1 2 3 3
第3个着色方案:1 3 2 2
第4个着色方案:1 3 3 2
第5个着色方案:2 1 1 3
第6个着色方案:2 1 3 3
第7个着色方案:2 3 1 1
第8个着色方案:2 3 3 1
第9个着色方案:3 1 1 2
第10个着色方案:3 1 2 2
第11个着色方案:3 2 1 1
第12个着色方案:3 2 2 1
2. 回溯法
二、改进BF算法
分析最简单的串匹配算法(BF算法),简述如何改进BF算法
-
BF算法的原理
- 对比过程:从主串S的第pos个字符起和模式的第一个字符进行比较,若相等,则进行逐个比较后续字符;否则从主串的下一个字符起再重新和模式的字符比较.
2. 匹配结果:依次类推,直至模式T中的每个字符依次和主串S中的一个连续的字符序列相等,则匹配成功,函数返回值为和模式T中第一个字符相等的字符在主串S中的序号, 否则称匹配不成功,函数返回值为零
- 对比过程:从主串S的第pos个字符起和模式的第一个字符进行比较,若相等,则进行逐个比较后续字符;否则从主串的下一个字符起再重新和模式的字符比较.
-
BF算法的缺陷
- 主串移动慢:当遇到主串和子串不相同情况时,主串只向前移动一位,而实际存在许多已经不匹配的主串字符串不能直接跳过
- 时间复杂度高:由于本算法基于蛮力法,对主串进行逐一遍历,时间复杂度非常高,浪费大量不必要的时间
-
BF算法改进
- 设置next数组: 给对比子串设置一个next数组,记录当前字符与开始重复出现的子串长度
- 修改对比方式:当遇到主串和子串不匹配的情况,首先对查找子串当前当前最大匹配的尾部字符,查找next表格,找到最大重用子序列,并移动子串,与主串进行对比
- 重复操作:当依旧不匹配时,重复操作2,直到对应的数组下标等于-1时,不在对子串查找,而是将比对过的全部略过,重新匹配
三、改进冒泡法
简要叙述冒泡法,给出两种改进方法?
- 冒泡法的原理
- 相邻比较:从后往前依次比较相邻的元素。若是要按照升序排序,则后面的比前面的小,就交换这2个元素;降序则相反。
- 每轮尾部少一个比较数 对每一对相邻元素作同样的工作,从第一对到最后一对。一轮比较交换下来,最后的元素就会是最小(或最大)的数了,这个数就不用参与后面的比较操作了。
- 重复操作:针对所有的元素重复以上的步骤。
- 结束:持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
- 冒泡法的缺点
- 可能存在无效交换:每一轮存在相邻的数之间要进行交换,却只能选出一个当前比较序列的最大值或最小值
- 可能存在重复遍历:当序列存在部分或全部已满排序要求时,不需要进行多轮比较
- 提出改进方法
- 改变比较的规则
因为基础的冒泡法每一轮都要对相邻的进行比较和交换,而许多的交换是毫无意义的,首先,对整体数据进行扫描,找出本轮循环中,最大值或最小值,然后将它和当前参与比较的序列最尾部数值进行交换 - 设置标记位
因为基础的冒泡法没有检测已有数据是否已经按照指定的顺序排列好了的功能。我们可以加入一个标记,如果一趟循环下来,一次交换操作都没有发生,则说明剩下的数据都已经按照指定的顺序排列好了,排序操作可以结束了。
- 改变比较的规则
四、城市旅游问题
某市场营销人员从他所在城市(项点1)出发,到其他5个城市去做市场调查,如下图所示。请设计行走路线。
1.贪心法
- 将顶点1存入路径列表
- 从顶点1出发,找出所有的可到达的点,挑选出距离最小的顶点,将它和其对应距离存入路径列表中
- 将新顶点作为起点,找出所有的可到达的点,排除路径记录中已走过的点,挑选出距离最小的顶点,将它和其对应累加后的距离,存入到路径列表中
- 重复操作2,一直到路径记录中包含所有的点
- 此时的唯一路径就是本次的行走路线
五、0/1背包问题
注: 参考前面复习归纳
六、最大子串问题
1. 穷举法
-
基本思路
1. 遍历数组,寻找正数:从主串的第一个数字开始,遍历主串,当发现主串的某一位置的值大于0时,将其作为子串的第一个数值,记录当前位置
2. 存放子串:继续遍历主串,每扫描主串的一个元素就对其求和,记录存放一个子串
3. 重复操作:返回到记录位置+1,继续重复操作1和2,直到整个主串遍历完成 -
关键代码
for(i=0;i<len;i++)
{if (a[i]>0){for(int j=i;j<len;j++){save(i,j);}}
}
2.动态规划法
-
基本思路
前面子序列之和- 大于0,保留b=b+a[i]
- 小于等于0,则丢弃,令b=a[i]
- 记录每一轮的最大长度
-
关键代码
b=0
sum=0
for(int i=0;i<n;i++)
{if (b>0)b+=a[i];elseb=a[i];if(b>sum)sum=b;
}
七.哈夫曼编号
1.权值排序
2.绘图
3.编码
4.演示合并过程
5.计算权值
八.棋盘覆盖
-
题目分析
·1. 特殊方格:在一个由2∧k个方格为边长组成的棋盘中,若恰有一个方格与其他方格不同
2. 前提条件:对于4∧k中特殊方格情况。用4种不同的L型骨牌覆盖一个给定的特殊棋盘上除去特殊方格外的所有方格,且任何两个L型骨牌不得重复覆盖
3. 使用L骨牌的个数:剩下的方格用到的L型骨盘数恰为(4^k-1)/3。 -
使用的方法:实现这个问题的方法其中之一就有分治法,将一个大问题,分为若干个解决办法类似的小问题来解决。
-
解题思路:可以将开始的大棋盘均分为四个小棋盘,其中原来的特殊方格一定在某一个小方格中,剩下三个没有特殊方格,若想要用分治法解决必须加上特殊方格。则需要在没有特殊方格的三个小方格角的地方分别加上一个新的特殊方格(这样三个特殊方格刚好组成一个L型骨牌),然后把这种方法递归到各个小棋盘上即可。
九.算法复杂度
- 算法的时间复杂度:反映了程序执行时间随输入规模增长而增长
的量级,在很大程度上能很好反映出算法的优劣与否.(若没有特别声明,时间复杂度就是指最坏时间复杂度。) - 两个算法的时间频度不一样,但很有可能拥有相同的时间复杂度。
- 常见的算法时间复杂度由小到大依次为:
实际演练
练习题
执行完下列语句段后
int f(int x)
{ return ((x>0)?x*f(x-1):2);
}int i;
i=f(f(1));
(1)请问值为多少。
f(1)=1f(0)=2
f(2)=2f(1)=4
f(f(1))=f(2)=4
(2)并简要分析该算法执行过程。
更多推荐
计算机算法与设计复习4(各类题型,逐一击破)
发布评论