算法设计与分析所有程序
- 格式:doc
- 大小:263.50 KB
- 文档页数:70
计算机算法的设计与分析计算机算法的设计和分析随着计算机技术的不断发展,算法成为了关键的核心技术之一。
算法的设计和分析是指通过一系列的步骤和方法来解决计算机问题的过程。
本文将详细介绍计算机算法的设计和分析。
一、算法设计的步骤:1. 理解和定义问题:首先需要明确所要解决的问题,并对其进行深入的理解,确定问题的输入和输出。
2. 分析问题:对问题进行分析,确定问题的规模、特点和约束条件,以及可能存在的问题解决思路和方法。
3. 设计算法:根据问题的性质和特点,选择合适的算法设计方法,从而得到解决问题的具体算法。
常见的算法设计方法包括贪心算法、分治算法、动态规划算法等。
4. 实现算法:将步骤3中设计的算法转化为计算机程序,并确保程序的正确性和可靠性。
5. 调试和测试算法:对实现的算法进行调试和测试,包括样本测试、边界测试、异常输入测试等,以验证算法的正确性和效率。
二、算法分析的步骤:1. 理解算法的效率:算法的效率是指算法解决问题所需的时间和空间资源。
理解算法的时间复杂度和空间复杂度是进行算法分析的基础。
2. 计算时间复杂度:时间复杂度用来表示算法解决问题所需的时间量级。
常用的时间复杂度包括常数时间O(1)、对数时间O(logn)、线性时间O(n)、平方时间O(n^2)等。
3. 计算空间复杂度:空间复杂度用来表示算法解决问题所需的空间资源量级。
常用的空间复杂度包括常数空间O(1)、线性空间O(n)、指数空间O(2^n)等。
4. 分析算法的最坏情况和平均情况:算法的最坏情况时间复杂度和平均情况时间复杂度是进行算法分析的关键指标。
最坏情况时间复杂度表示在最不利条件下算法所需的时间量级,平均情况时间复杂度表示在一般情况下算法所需的时间量级。
5. 比较算法的优劣:通过对不同算法的时间复杂度和空间复杂度进行分析,可以对算法的优劣进行比较,从而选择合适的算法。
三、常见的算法设计与分析方法:1. 贪心算法:贪心算法通过每一步的选择来寻求最优解,并且这些选择并不依赖于其他选择。
算法设计与分析黄丽韵版(1)用计算机求解问题的步骤:1、问题分析2、数学模型建立3、算法设计与选择4、算法指标5、算法分析6、算法实现7、程序调试8、结果整理文档编制(2)算法定义:算法是指在解决问题时,按照某种机械步骤一定可以得到问题结果的处理过程(3)算法的三要素1、操作2、控制结构3、数据结构算法具有以下5个属性:有穷性:一个算法必须总是在执行有穷步之后结束,且每一步都在有穷时间内完成。
确定性:算法中每一条指令必须有确切的含义。
不存在二义性。
只有一个入口和一个出可行性:一个算法是可行的就是算法描述的操作是可以通过已经实现的基本运算执行有限次来实现的。
输入:一个算法有零个或多个输入,这些输入取自于某个特定对象的集合。
输出:一个算法有一个或多个输出,这些输出同输入有着某些特定关系的量。
算法设计的质量指标:正确性:算法应满足具体问题的需求;可读性:算法应该好读,以有利于读者对程序的理解:健壮性:算法应具有容错处理,当输入为非法数据时,算法应对其作出反应,而不是产生莫名其妙的输出结果。
效率与存储量需求:效率指的是算法执行的时间;存储量需求指算法执行过程中所需要的最大存储空间。
一般这两者与问题的规模有关。
经常采用的算法主要有迭代法、分而治之法、贪婪法、动态规划法、回溯法、分支限界法迭代法也称“辗转法”,是一种不断用变量的旧值递推出新值的解决问题的方法。
迭代法也称“辗转法”,是一种不断用变量的旧值递推出新值的解决问题的方利用迭代算法解决问题,需要做好以下三个方面的工作:一、确定迭代模型。
在可以用迭代算法解决的问题中,至少存在一个直接或间接地不断由旧值递推出新值的变量,这个变量就是迭代变量。
二、建立迭代关系式。
所谓迭代关系式,指如何从变量的前一个值推出其下一个值的公式(或关系)。
迭代关系式的建立是解决迭代问题的关键,通常可以使用递推或倒推的方法来完成。
三、对迭代过程进行控制。
在什么时候结束迭代过程?这是编写迭代程序必须考虑的问题。
算法设计与分析算法是计算机科学中的核心概念,它是解决问题的一系列步骤和规则的有序集合。
在计算机科学的发展中,算法设计和分析扮演着至关重要的角色。
本文将探讨算法设计和分析的相关概念、技术和重要性。
一、算法设计的基本原则在设计算法时,需要遵循一些基本原则来确保其正确性和有效性:1. 正确性:算法设计应确保能够正确地解决给定的问题,即输出与预期结果一致。
2. 可读性:设计的算法应具有清晰的结构和逻辑,易于理解和维护。
3. 高效性:算法应尽可能地减少时间和空间复杂度,以提高执行效率。
4. 可扩展性:算法应具备良好的扩展性,能够适应问题规模的变化和增长。
5. 可靠性:设计的算法应具备稳定性和鲁棒性,对不同的输入都能给出正确的结果。
二、常见的算法设计技术1. 枚举法:按照规定的顺序逐个尝试所有可能的解,直到找到满足条件的解。
2. 递归法:通过将一个大问题分解成若干个小问题,并通过递归地解决小问题,最终解决整个问题。
3. 贪心算法:在每个阶段选择最优解,以期望通过一系列局部最优解达到全局最优解。
4. 分治算法:将一个大问题划分成多个相互独立的子问题,逐个解决子问题,并将解合并得到整体解。
5. 动态规划:通过将一个大问题分解成多个小问题,并存储已解决子问题的结果,避免重复计算。
三、算法分析的重要性算法分析可以评估算法的效率和性能。
通过算法分析,可以:1. 预测算法在不同规模问题上的表现,帮助选择合适的算法解决具体问题。
2. 比较不同算法在同一问题上的性能,从而选择最优的算法。
3. 评估算法在不同硬件环境和数据集上的表现,选择最适合的算法实现。
四、常见的算法分析方法1. 时间复杂度:衡量算法所需执行时间的增长率,常用的时间复杂度有O(1)、O(log n)、O(n)、O(n log n)和O(n^2)等。
2. 空间复杂度:衡量算法所需占用存储空间的增长率,常用的空间复杂度有O(1)、O(n)和O(n^2)等。
3. 最坏情况分析:对算法在最不利情况下的性能进行分析,可以避免算法性能不稳定的问题。
实验一找最大和最小元素与归并分类算法实现(用分治法)一、实验目的1.掌握能用分治法求解的问题应满足的条件;2.加深对分治法算法设计方法的理解与应用;3.锻炼学生对程序跟踪调试能力;4.通过本次实验的练习培养学生应用所学知识解决实际问题的能力。
二、实验内容1、找最大和最小元素输入n 个数,找出最大和最小数的问题。
2、归并分类将一个含有n个元素的集合,按非降的次序分类(排序)。
三、实验要求(1)用分治法求解问题(2)上机实现所设计的算法;四、实验过程设计(算法设计过程)1、找最大和最小元素采用分治法,将数组不断划分,进行递归。
递归结束的条件为划分到最后若为一个元素则max和min都是这个元素,若为两个取大值赋给max,小值给min。
否则就继续进行划分,找到两个子问题的最大和最小值后,比较这两个最大值和最小值找到解。
2、归并分类使用分治的策略来将一个待排序的数组分成两个子数组,然后递归地对子数组进行排序,最后将排序好的子数组合并成一个有序的数组。
在合并过程中,比较两个子数组的首个元素,将较小的元素放入辅助数组,并指针向后移动,直到将所有元素都合并到辅助数组中。
五、源代码1、找最大和最小元素#include<iostream>using namespace std;void MAXMIN(int num[], int left, int right, int& fmax, int& fmin); int main() {int n;int left=0, right;int fmax, fmin;int num[100];cout<<"请输入数字个数:";cin >> n;right = n-1;cout << "输入数字:";for (int i = 0; i < n; i++) {cin >> num[i];}MAXMIN(num, left, right, fmax, fmin);cout << "最大值为:";cout << fmax << endl;cout << "最小值为:";cout << fmin << endl;return 0;}void MAXMIN(int num[], int left, int right, int& fmax, int& fmin) { int mid;int lmax, lmin;int rmax, rmin;if (left == right) {fmax = num[left];fmin = num[left];}else if (right - left == 1) {if (num[right] > num[left]) {fmax = num[right];fmin = num[left];}else {fmax = num[left];fmin = num[right];}}else {mid = left + (right - left) / 2;MAXMIN(num, left, mid, lmax, lmin);MAXMIN(num, mid+1, right, rmax, rmin);fmax = max(lmax, rmax);fmin = min(lmin, rmin);}}2、归并分类#include<iostream>using namespace std;int num[100];int n;void merge(int left, int mid, int right) { int a[100];int i, j,k,m;i = left;j = mid+1;k = left;while (i <= mid && j <= right) {if (num[i] < num[j]) {a[k] = num[i++];}else {a[k] = num[j++];}k++;}if (i <= mid) {for (m = i; m <= mid; m++) {a[k++] = num[i++];}}else {for (m = j; m <= right; m++) {a[k++] = num[j++];}}for (i = left; i <= right; i++) { num[i] = a[i];}}void mergesort(int left, int right) { int mid;if (left < right) {mid = left + (right - left) / 2;mergesort(left, mid);mergesort(mid + 1, right);merge(left, mid, right);}}int main() {int left=0,right;int i;cout << "请输入数字个数:";cin >> n;right = n - 1;cout << "输入数字:";for (i = 0; i < n; i++) {cin >> num[i];}mergesort(left,right);for (i = 0; i < n; i++) {cout<< num[i];}return 0;}六、运行结果和算法复杂度分析1、找最大和最小元素图1-1 找最大和最小元素结果算法复杂度为O(logn)2、归并分类图1-2 归并分类结果算法复杂度为O(nlogn)实验二背包问题和最小生成树算法实现(用贪心法)一、实验目的1.掌握能用贪心法求解的问题应满足的条件;2.加深对贪心法算法设计方法的理解与应用;3.锻炼学生对程序跟踪调试能力;4.通过本次实验的练习培养学生应用所学知识解决实际问题的能力。
《计算机算法设计与分析》课程设计用分治法解决快速排序问题及用动态规划法解决最优二叉搜索树问题及用回溯法解决图的着色问题一、课程设计目的:《计算机算法设计与分析》这门课程是一门实践性非常强的课程,要求我们能够将所学的算法应用到实际中,灵活解决实际问题。
通过这次课程设计,能够培养我们独立思考、综合分析与动手的能力,并能加深对课堂所学理论和概念的理解,可以训练我们算法设计的思维和培养算法的分析能力。
二、课程设计内容:1、分治法:(2)快速排序;2、动态规划:(4)最优二叉搜索树;3、回溯法:(2)图的着色。
三、概要设计:分治法—快速排序:分治法的基本思想是将一个规模为n的问题分解为k个规模较小的子问题,这些子问题互相独立且与原问题相同。
递归地解这些子问题,然后将各个子问题的解合并得到原问题的解。
分治法的条件:(1) 该问题的规模缩小到一定的程度就可以容易地解决;(2) 该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质;(3) 利用该问题分解出的子问题的解可以合并为该问题的解;(4) 该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子子问题。
抽象的讲,分治法有两个重要步骤:(1)将问题拆开;(2)将答案合并;动态规划—最优二叉搜索树:动态规划的基本思想是将问题分解为若干个小问题,解子问题,然后从子问题得到原问题的解。
设计动态规划法的步骤:(1)找出最优解的性质,并刻画其结构特征;(2)递归地定义最优值(写出动态规划方程);(3)以自底向上的方式计算出最优值;(4)根据计算最优值时得到的信息,构造一个最优解。
●回溯法—图的着色回溯法的基本思想是确定了解空间的组织结构后,回溯法就是从开始节点(根结点)出发,以深度优先的方式搜索整个解空间。
这个开始节点就成为一个活结点,同时也成为当前的扩展结点。
在当前的扩展结点处,搜索向纵深方向移至一个新结点。
这个新结点就成为一个新的或节点,并成为当前扩展结点。
算法设计与分析报告学生姓名学号专业班级指导教师完成时间目录一、课程内容 (3)二、算法分析 (3)1、分治法 (3)(1)分治法核心思想 (3)(2)MaxMin算法分析 (3)2、动态规划 (4)(1)动态规划核心思想 (4)(2)矩阵连乘算法分析 (5)3、贪心法 (5)(1)贪心法核心思想 (5)(2)背包问题算法分析 (6)(3)装载问题算法分析 (7)4、回溯法 (7)(1)回溯法核心思想 (7)(2)N皇后问题非递归算法分析 (7)(3)N皇后问题递归算法分析 (8)三、例子说明 (9)1、MaxMin问题 (9)2、矩阵连乘 (10)3、背包问题 (10)4、最优装载 (10)5、N皇后问题(非递归) (11)6、N皇后问题(递归) (11)四、心得体会 (12)五、算法对应的例子代码 (12)1、求最大值最小值 (12)2、矩阵连乘问题 (13)3、背包问题 (15)4、装载问题 (17)5、N皇后问题(非递归) (19)6、N皇后问题(递归) (20)一、课程内容1、分治法,求最大值最小值,maxmin算法;2、动态规划,矩阵连乘,求最少连乘次数;3、贪心法,1)背包问题,2)装载问题;4、回溯法,N皇后问题的循环结构算法和递归结构算法。
二、算法分析1、分治法(1)分治法核心思想当要求解一个输入规模为n,且n的取值相当大的问题时,直接求解往往是非常困难的。
如果问题可以将n个输入分成k个不同子集合,得到k个不同的可独立求解的子问题,其中1<k≤n, 而且子问题与原问题性质相同,原问题的解可由这些子问题的解合并得出。
那末,这类问题可以用分治法求解。
分治法的核心技术1)子问题的划分技术.2)递归技术。
反复使用分治策略将这些子问题分成更小的同类型子问题,直至产生出不用进一步细分就可求解的子问题。
3)合并技术.(2)MaxMin算法分析问题:在含有n个不同元素的集合中同时找出它的最大和最小元素。
《算法设计与分析》教案张静第1章绪论算法理论的两大论题:1. 算法设计2. 算法分析1.1 算法的基本概念1.1.1 为什么要学习算法理由1:算法——程序的灵魂➢问题的求解过程:分析问题→设计算法→编写程序→整理结果➢程序设计研究的四个层次:算法→方法学→语言→工具理由2:提高分析问题的能力算法的形式化→思维的逻辑性、条理性1.1.2 算法及其重要特性算法(Algorithm):对特定问题求解步骤的一种描述,是指令的有限序列。
算法的五大特性:⑴输入:一个算法有零个或多个输入。
⑵输出:一个算法有一个或多个输出。
⑶有穷性:一个算法必须总是在执行有穷步之后结束,且每一步都在有穷时间内完成。
⑷确定性:算法中的每一条指令必须有确切的含义,对于相同的输入只能得到相同的输出。
⑸可行性:算法描述的操作可以通过已经实现的基本操作执行有限次来实现。
1.1.3 算法的描述方法⑴自然语言优点:容易理解缺点:冗长、二义性使用方法:粗线条描述算法思想注意事项:避免写成自然段欧几里德算法⑶程序设计语言优点:能由计算机执行缺点:抽象性差,对语言要求高使用方法:算法需要验证注意事项:将算法写成子函数欧几里德算法#include <iostream.h>int CommonFactor(int m, int n) {int r=m % n;while (r!=0){m=n;n=r;r=m % n;}return n;}void main( ){cout<<CommonFactor(63, 54)<<endl;}⑷伪代码——算法语言伪代码(Pseudocode):介于自然语言和程序设计语言之间的方法,它采用某一程序设计语言的基本语法,操作指令可以结合自然语言来设计。
优点:表达能力强,抽象性强,容易理解使用方法:7 ± 2欧几里德算法1. r = m % n;2. 循环直到 r 等于02.1 m = n;2.2 n = r;2.3 r = m % n;3. 输出 n ;1.1.4 算法设计的一般过程1.理解问题2.预测所有可能的输入3. 在精确解和近似解间做选择4. 确定适当的数据结构5.算法设计技术6.描述算法7.跟踪算法8.分析算法的效率9.根据算法编写代码1.2 算法分析算法分析(Algorithm Analysis):对算法所需要的两种计算机资源——时间和空间进行估算➢时间复杂性(Time Complexity)➢空间复杂性(Space Complexity)算法分析的目的:➢设计算法——设计出复杂性尽可能低的算法➢选择算法——在多种算法中选择其中复杂性最低者时间复杂性分析的关键:➢ 问题规模:输入量的多少;➢ 基本语句:执行次数与整个算法的执行时间成正比的语句for (i=1; i<=n; i++)for (j=1; j<=n; j++)x++;问题规模:n基本语句:x++1.2.1 渐进符号1. 大O 符号定义1.1 若存在两个正的常数c 和n 0,对于任意n ≥n 0,都有T (n )≤c ×f (n ),则称T (n )=O (f (n ))2. 大Ω符号定义1.2 若存在两个正的常数c 和n 0,对于任意n ≥n 0,都有T (n )≥c ×g (n ),则称T (n )=Ω(g (n ))问题规模n 执行次3. Θ符号定义1.3 若存在三个正的常数c 1、c 2和n 0,对于任意n ≥n 0都有c 1×f (n )≥T (n )≥c 2×f (n ),则称T (n )=Θ(f (n ))例: T (n )=5n 2+8n +1当n ≥1时,5n 2+8n +1≤5n 2+8n +n=5n 2+9n ≤5n 2+9n 2≤14n 2=O (n 2)当n ≥1时,5n 2+8n +1≥5n 2=Ω(n 2)∴ 当n ≥1时,14n 2≥5n 2+8n +1≥5n 2则:5n 2+8n +1=Θ(n 2)0问题规模n 执行次数问题规模n 执行次数定理 1.1 若T(n)=amnm +am-1nm-1 + … +a1n+a0(am>0),则有T(n)=O(nm)且T(n)=Ω(n m),因此,有T(n)=Θ(n m)。
本科实验报告课程名称:算法设计与分析实验项目:递归与分治算法实验地点:计算机系实验楼110专业班级:物联网1601 学号:2016002105 学生姓名:俞梦真指导教师:郝晓丽2018年05月04 日实验一递归与分治算法1.1 实验目的与要求1.进一步熟悉C/C++语言的集成开发环境;2.通过本实验加深对递归与分治策略的理解和运用。
1.2 实验课时2学时1.3 实验原理分治(Divide-and-Conquer)的思想:一个规模为n的复杂问题的求解,可以划分成若干个规模小于n的子问题,再将子问题的解合并成原问题的解。
需要注意的是,分治法使用递归的思想。
划分后的每一个子问题与原问题的性质相同,可用相同的求解方法。
最后,当子问题规模足够小时,可以直接求解,然后逆求原问题的解。
1.4 实验题目1.上机题目:格雷码构造问题Gray码是一个长度为2n的序列。
序列无相同元素,每个元素都是长度为n的串,相邻元素恰好只有一位不同。
试设计一个算法对任意n构造相应的Gray码(分治、减治、变治皆可)。
对于给定的正整数n,格雷码为满足如下条件的一个编码序列。
(1)序列由2n个编码组成,每个编码都是长度为n的二进制位串。
(2)序列中无相同的编码。
(3)序列中位置相邻的两个编码恰有一位不同。
2.设计思想:根据格雷码的性质,找到他的规律,可发现,1位是0 1。
两位是00 01 11 10。
三位是000 001 011010 110 111 101 100。
n位是前n-1位的2倍个。
N-1个位前面加0,N-2为倒转再前面再加1。
3.代码设计:}}}int main(){int n;while(cin>>n){get_grad(n);for(int i=0;i<My_grad.size();i++)cout<<My_grad[i]<<endl;My_grad.clear();}return 0;}运行结果:1.5 思考题(1)递归的关键问题在哪里?答:1.递归式,就是如何将原问题划分成子问题。
《算法设计与分析》课程实验报告实验序号:04实验项目名称:实验4 分治法(三)一、实验题目1.邮局选址问题问题描述:在一个按照东西和南北方向划分成规整街区的城市里,n个居民点散乱地分布在不同的街区中。
用x 坐标表示东西向,用y坐标表示南北向。
各居民点的位置可以由坐标(x,y)表示。
街区中任意2 点(x1,y1)和(x2,y2)之间的距离可以用数值∣x1−x2∣+∣y1−y2∣度量。
居民们希望在城市中选择建立邮局的最佳位置,使n个居民点到邮局的距离总和最小。
编程任务:给定n 个居民点的位置,编程计算邮局的最佳位置。
2.最大子数组问题问题描述:对给定数组A,寻找A的和最大的非空连续子数组。
3.寻找近似中值问题描述:设A是n个数的序列,如果A中的元素x满足以下条件:小于x的数的个数≥n/4,且大于x的数的个数≥n/4 ,则称x为A的近似中值。
设计算法求出A的一个近似中值。
如果A中不存在近似中值,输出false,否则输出找到的一个近似中值4.循环赛日程表问题描述:设有n=2^k个运动员要进行网球循环赛。
现要设计一个满足以下要求的比赛日程表:每个选手必须与其他n-1个选手各赛一次,每个选手一天只能赛一次,循环赛一共进行n-1天。
二、实验目的(1)进一步理解分治法解决问题的思想及步骤(2)体会分治法解决问题时递归及迭代两种不同程序实现的应用情况之差异(3)熟练掌握分治法的自底向上填表实现(4)将分治法灵活于具体实际问题的解决过程中,重点体会大问题如何分解为子问题及每一个大问题涉及哪些子问题及子问题的表示。
三、实验要求(1)写清算法的设计思想。
(2)用递归或者迭代方法实现你的算法,并分析两种实现的优缺点。
(3)根据你的数据结构设计测试数据,并记录实验结果。
(4)请给出你所设计算法的时间复杂度的分析,如果是递归算法,请写清楚算法执行时间的递推式。
四、实验过程(算法设计思想、源码)1.邮局选址问题(1)算法设计思想根据题目要求,街区中任意2 点(x1,y1)和(x2,y2)之间的距离可以用数值∣x1−x2∣+∣y1−y2∣度量。
算法设计与分析实验指导书东北大学软件学院2014年目录算法设计与分析 (1)实验指导书 (1)前言 (3)实验要求 (4)实验1 分治法的应用(2学时) (5)1.实验目的 (5)2.实验类型 (5)3.预习要求 (5)4.实验基本要求 (5)5.实验基本步骤 (7)实验2动态规划(2学时) (9)1.实验目的 (9)2.实验类型 (9)3.预习要求 (9)4.实验基本要求 (9)5.实验基本步骤 (10)实验3 回溯法(4学时) (12)1.实验目的 (12)2.实验类型 (12)3.预习要求 (12)4.实验基本要求 (12)5.实验基本步骤 (13)前言《算法设计与分析》是一门面向设计,处于计算机科学与技术学科核心地位的教育课程。
通过对计算机算法系统的学习,使学生理解和掌握计算机算法的通用设计方法,培养对算法的计算复杂性正确分析的能力,为独立设计算法和对算法进行复杂性分析奠定基础。
要求掌握算法复杂度分析、分治法、动态规划法、贪心法、回溯法、分支限界法等算法的设计方法及其分析方法。
能将这些方法灵活的应用到相应的问题中,并且能够用C++实现所涉及的算法,并尽量做到低复杂度,高效率。
通过本课程的实验,使学生加深对课程内容的理解,培养学生严密的思维能力,运用所学知识结合具体问题设计适用的算法的能力;培养学生良好的设计风格,激励学生创造新算法和改进旧算法的愿望和热情。
希望同学们能够充分利用实验条件,认真完成实验,从实验中得到应有的锻炼和培养。
希望同学们在使用本实验指导书及进行实验的过程中,能够帮助我们不断地发现问题,并提出建议,使《算法设计与分析》课程成为对大家有益的课程。
实验要求《算法设计与分析》课程实验的目的是为了使学生在课堂学习的同时,通过一系列的实验,使学生加深理解和更好地掌握《算法设计与分析》课程教学大纲要求的内容。
在《算法设计与分析》的课程实验过程中,要求学生做到:(1)仔细观察调试程序过程中出现的各种问题,记录主要问题,做出必要说明和分析。
HUNAN CITY UNIVERSITY 算法设计与分析课程设计题目:求最大值与最小值问题专业:学号:姓名:指导教师:成绩:二0年月日一、问题描述输入一列整数,求出该列整数中的最大值与最小值。
二、课程设计目的通过课程设计,提高用计算机解决实际问题的能力,提高独立实践的能力,将课本上的理论知识和实际有机的结合起来,锻炼分析解决实际问题的能力。
提高适应实际,实践编程的能力。
在实际的编程和调试综合试题的基础上,把高级语言程序设计的思想、编程巧和解题思路进行总结与概括,通过比较系统地练习达到真正比较熟练地掌握计算机编程的基本功,为后续的学习打下基础。
了解一般程序设计的基本思路与方法。
三、问题分析看到这个题目我们最容易想到的算法是直接比较算法:将数组的第 1 个元素分别赋给两个临时变量:fmax:=A[1]; fmin:=A[1]; 然后从数组的第 2 个元素 A[2]开始直到第 n个元素逐个与 fmax 和 fmin 比较,在每次比较中,如果A[i] > fmax,则用 A[i]的值替换 fmax 的值;如果 A[i] < fmin,则用 A[i]的值替换 fmin 的值;否则保持 fmax(fmin)的值不变。
这样在程序结束时的fmax、fmin 的值就分别是数组的最大值和最小值。
这个算法在最好、最坏情况下,元素的比较次数都是 2(n-1),而平均比较次数也为 2(n-1)。
如果将上面的比较过程修改为:从数组的第 2 个元素 A[2]开始直到第 n 个元素,每个 A[i]都是首先与 fmax 比较,如果 A[i]>fmax,则用 A[i]的值替换 fmax 的值;否则才将 A[i]与 fmin 比较,如果 A[i] < fmin,则用 A[i]的值替换 fmin 的值。
这样的算法在最好、最坏情况下使用的比较次数分别是 n-1 和 2(n-1),而平均比较次数是 3(n-1)/2,因为在比较过程中,将有一半的几率出现 A[i]>fmax 情况。
目录第二章递归与分治 (3)1、用递归思想求N! (3)2、用递归思想求Fibonacci数列 (3)3、用递归思想求排列问题 (4)4、用递归思想求整数划分问题 (5)5、用递归思想求汉诺塔问题 (6)6、用递归思想实现插入排序 (7)7、用分治思想实现二分查找 (8)8、用分治法求两个大整数的乘法 (9)9、用分治思想求一个数组的最大值与最小值 (10)10、用分法思想实现合并排序 (12)11、用分治思想实现快速排序 (13)12、用分治法实现线性时间选择问题 (15)13、用分法思想实现残缺棋盘问题 (15)第三章动态规划法 (18)1、矩阵连乘问题 (18)2、最长公子序列 (20)3、最大子段和问题 (23)4、图像压缩问题 (28)5、电路布线问题 (31)6、最 (31)7、最 (31)第四章贪心算法 (32)1、哈夫曼编码 (32)4、Kruskal算法求最小生成树 (35)5、集装箱问题 (38)6、活动安排问题 (40)第五章回溯法 (42)1、用回溯法求0-1背包问题 (42)2、用回溯法求N皇后问题 (45)3、用回溯法求旅行售货员问题 (46)4、用回溯法求圆排列问题 (48)5、用回溯法求符号三角形问题 (50)6、用回溯法求批处理作业调度问题 (52)7、用回溯法求连续邮资问题 (54)8、用回溯法求图的m着色问题 (57)9、用回溯法求最大团问题 (59)第六章回溯法 (62)1、用分支限界法求0-1背包问题 (62)第二章递归与分治1、用递归思想求N!王晓东版——《计算机算法设计与分析(第四版)》P11页,例2-12、用递归思想求Fibonacci数列王晓东版——《计算机算法设计与分析(第四版)》P12页,例2-23、用递归思想求排列问题王晓东版——《计算机算法设计与分析(第四版)》P13页,例2-4N个元素的全排列的个数为:N!本算法非常重要,因为它是很多算法的基础,比如回溯法那章里的算法很多都是以本算法为基础的。
4、用递归思想求整数划分问题王晓东版——《计算机算法设计与分析(第四版)》P14页,例2-5整数划分问题是算法中的一个经典命题之一,有关这个问题的讲述在讲解到递归时基本都将涉及。
所谓整数划分,是指把一个正整数n写成如下形式:n=m1+m2+……+mi; (其中mi为正整数,并且1 <= mi <= n),则{m1,m2,...,mi}为n的一个划分。
如果{m1,m2,...,mi}中的最大值不超过m,即max(m1,m2,...,mi)<=m,则称它属于n的一个m划分。
这里我们记n的m划分的个数为f(n,m);例如,但n=4时,他有5个划分,{4},{3,1},{2,2},{2,1,1},{1,1,1,1};注意4=1+3 和4=3+1被认为是同一个划分。
该问题是求出n的所有划分个数,即f(n, n)。
下面我们考虑求f(n,m)的方法;根据n和m的关系,考虑以下几种情况:(1) 当n=1 时,不论m的值为多少(m>0),只有一种划分即{1};(2) 当m=1 时,不论n的值为多少,只有一种划分即n个1,{1,1, 1, ..., 1 };(3) 当n=m 时,根据划分中是否包含n,可以分为两种情况:(a). 划分中包含n的情况,只有一个即{ n };(b). 划分中不包含n的情况,这时划分中最大的数字也一定比n 小,即n 的所有( n - 1 ) 划分。
因此f(n, n) = 1 + f(n, n-1);(4) 当n < m 时,由于划分中不可能出现负数,因此就相当于f(n, n);(5) 但n > m 时,根据划分中是否包含最大值m,可以分为两种情况:(a). 划分中包含m的情况,即{m,{x1,x2, ...,xi}},其中{x1,x2, ...,xi }的和为n-m,可能再次出现m,因此是(n-m)的m划分,因此这种划分个数为f(n-m, m);(b). 划分中不包含m的情况,则划分中所有值都比m小,即n的(m-1)划分个数为f(n, m - 1);因此f(n, m) = f(n-m, m) + f(n, m-1);综合以上情况,我们可以看出,上面的结论具有递归定义特征,其中(1)和(2)属于回归条件,(3)和(4)属于特殊情况,将会转换为情况(5)。
而情况(5)为通用情况,属于递推的方法,其本质主要是通过减小m以达到回归条件,从而解决问题。
其递推表达式f(n, m) = 1; ( n = 1 or m = 1 )f(n, m) = f(n, n); ( n < m )f(n, m) = 1+ f(n, m - 1); ( n = m )f(n, m) = f(n - m, m) + f(n, m - 1); ( n > m )因此我们可以给出求出f(n, m) 的递归函数代码如下。
怎样求出具体的划分结果呢?这个问题比较难解决,等进一步分析。
5、用递归思想求汉诺塔问题6、用递归思想实现插入排序#include <stdio.h>#include <stdlib.h>#include <time.h>void insertSort(int *aa,int n){if(n>0){n = n-1;insertSort(aa,n);int a= aa[n];int k = n-1;while((k>=0)&& a<aa[k]){aa[k+1] = aa[k];k--;}aa[k+1] = a;}}void main(){int a[10];srand((unsigned int)time(NULL));for(int i=0;i<10;i++){a[i] = rand()%100;printf("%d ",a[i]);}printf("\n");insertSort(a,10);for(i=0;i<10;i++)printf("%d ",a[i]);printf("\n");}7、用分治思想实现二分查找8、用分治法求两个大整数的乘法最简单的方法,这里没有体现分治法的思想9、用分治思想求一个数组的最大值与最小值10、用分法思想实现合并排序11、用分治思想实现快速排序如果每次划分不以a[p]为基准,而是随机从a[p]-a[r]里取一个数为基准,则可以设计如下随12、用分治法实现线性时间选择问题本算法要用到上面快速排序的随机划分算法13、用分法思想实现残缺棋盘问题王晓东版——《计算机算法设计与分析(第四版)》P20页,例2.6注意:同一种形状的骨牌,在填充时数字不一样,关键看三个相同数字摆放位置所构成的形状。
第三章动态规划法1、矩阵连乘问题2、最长公子序列3、最大子段和问题(1)分治思路实现(2)动态规划思路实现补充了书本上不完美的地方:在求最大子段和,随便可以求出最大子段和的起始坐标和终止坐标;在求最大子矩阵和时,可以随便求出子矩阵的左上角和右下角坐标。
4、图像压缩问题王晓东版——《计算机算法设计与分析(第四版)》P65页,例3.7书本上P67页上第一行b[j] = b[s[j]]行错误,本程序修正了这个错误,在求每段的最大位数时,只需要从头到位扫描一次,时间复杂度为O(n)。
小有成就感^_^5、电路布线问题6、最7、最第四章贪心算法1、哈夫曼编码4、Kruskal算法求最小生成树设有如下无向图,求这个图的最小生成树。
判断两个节点是否连通,用并查集结构来实现。
5、集装箱问题6、活动安排问题第五章回溯法回溯法的基本步骤(1)针对所给问题,定义问题的解空间;(2)确定易于搜索的解空间结构;(3)以深度优先方式搜索解空间,并在搜索过程中用剪枝函数避免无效搜索。
回溯法的基本思想在搜索的过程中动态产生问题的解空间。
在任何时刻,算法只保存从根结点到当前扩展结点的路径,这可以节省大量的空间,如果将有的路径全部保存下来,将需要一个巨大的空间。
迭代回溯的算法基本框架(没有理解)void IterativeBacktrack(void){int t = 1;while(t>0){if( f(n,t) <= g(n,t)){for(int i= f(n,t);i<=g(n,t);i++){x[t] = h(i);if(Constraint(t) && Bound(t)){if(Solution(t))Output(x);elset++; // 向纵深方向搜索}}//end for}elset--;}}1、用回溯法求0-1背包问题0-1背包问题的解空间是一棵子集树2、用回溯法求N皇后问题问题描述:在一个N*N棋盘上,放置N个皇后,它们不能在同一行,同一列,以及同一斜线上。
3、用回溯法求旅行售货员问题问题描述:某售货员要到若干城市去推销商品,已知各城市之间的路程(或费用),他要选择一条从驻地出发,经过每个城市一遍,最后回到驻地的路线,使总的路程最短。
4、用回溯法求圆排列问题(1)问题描述给定n个大小不等的圆,将它们排在一个水平面上,求总水平长度最短的圆排列方式。
例如有3个半径分别1,1,2的圆,第一种排列方式为:前面放两个半径为1的小圆,后面跟一个半径为2的大圆,这种排列方式所占的总水平长度为5+2*sqrt(2)。
第二种排列方式为:半径为大圆放中间,两个小圆分别在两侧,这种排列方式所占的总长度为2+4*sqrt(2)。
所以对于同一组圆,不同的排列方式,得到的总水平长度是不一样的。