算法分析与设计实验一:分治策略
- 格式:doc
- 大小:2.64 MB
- 文档页数:13
实验一递归与分治策略一、实验目的1.加深学生对分治法算法设计方法的基本思想、基本步骤、基本方法的理解与掌握;2.提高学生利用课堂所学知识解决实际问题的能力;3.提高学生综合应用所学知识解决实际问题的能力。
二、实验内容1、①设a[0:n-1]是已排好序的数组。
请写二分搜索算法,使得当搜索元素x不在数组中时,返回小于x的最大元素位置i和大于x的最小元素位置j。
当搜索元素在数组中时,i和j相同,均为x在数组中的位置。
②写出三分搜索法的程序。
三、实验要求(1)用分治法求解上面两个问题;(2)再选择自己熟悉的其它方法求解本问题;(3)上机实现所设计的所有算法;四、实验过程设计(算法设计过程)1、已知a[0:n-1]是一个已排好序的数组,可以采用折半查找(二分查找)算法。
如果搜索元素在数组中,则直接返回下表即可;否则比较搜索元素x与通过二分查找所得最终元素的大小,注意边界条件,从而计算出小于x的最大元素的位置i和大于x的最小元素位置j。
2、将n个元素分成大致相同的三部分,取在数组a的左三分之一部分中继续搜索x。
如果x>a[2(n-1)/3],则只需在数组a的右三分之一部分中继续搜索x。
上述两种情况不成立时,则在数组中间的三分之一部分中继续搜索x。
五、实验结果分析二分搜索法:三分搜索法:时间复杂性:二分搜索每次把搜索区域砍掉一半,很明显时间复杂度为O(log n)。
(n代表集合中元素的个数)三分搜索法:O(3log3n)空间复杂度:O(1)。
六、实验体会本次试验解决了二分查找和三分查找的问题,加深了对分治法的理解,收获很大,同时我也理解到学习算法是一个渐进的过程,算法可能一开始不是很好理解,但是只要多看几遍,只看是不够的还要动手分析一下,这样才能学好算法。
七、附录:(源代码)二分搜索法:#include<iostream.h>#include<stdio.h>int binarySearch(int a[],int x,int n){int left=0;int right=n-1;int i,j;while(left<=right){int middle=(left+right)/2;if(x==a[middle]){i=j=middle;return 1;}if(x>a[middle])left=middle+1;else right=middle-1;}i=right;j=left;return 0;}int main(){ int a[10]={0,1,2,3,4,5,6,7,8,9};int n=10;int x=9;if(binarySearch(a,x,n))cout<<"找到"<<endl;elsecout<<"找不到"<<endl;return 0;}实验二动态规划——求解最优问题一、实验目的1.加深学生对动态规划算法设计方法的基本思想、基本步骤、基本方法的理解与掌握;2.提高学生利用课堂所学知识解决实际问题的能力;3.提高学生综合应用所学知识解决实际问题的能力。
《算法设计与分析》实验报告实验一递归与分治策略应用基础学号:**************姓名:*************班级:*************日期:2014-2015学年第1学期第九周一、实验目的1、理解递归的概念和分治法的基本思想2、了解适用递归与分治策略的问题类型,并能设计相应的分治策略算法3、掌握递归与分治算法时间空间复杂度分析,以及问题复杂性分析方法二、实验内容任务:以下题目要求应用递归与分治策略设计解决方案,本次实验成绩按百分制计,完成各小题的得分如下,每小题要求算法描述准确且程序运行正确。
1、求n个元素的全排。
(30分)2、解决一个2k*2k的特殊棋牌上的L型骨牌覆盖问题。
(30分)3、设有n=2k个运动员要进行网球循环赛。
设计一个满足要求的比赛日程表。
(40分)提交结果:算法设计分析思路、源代码及其分析说明和测试运行报告。
三、设计分析四、算法描述及程序五、测试与分析六、实验总结与体会#include "iostream"using namespace std;#define N 100void Perm(int* list, int k, int m){if (k == m){for (int i=0; i<m; i++)cout << list[i] << " ";cout << endl;return;}else{for (int i=m; i<k; i++){swap(list[m], list[i]);Perm(list, k, m+1);swap(list[m], list[i]);}}}void swap(int a,int b){int temp;temp=a;a=b;b=temp;}int main(){int i,n;int a[N];cout<<"请输入排列数据总个数:";cin>>n;cout<<"请输入数据:";for(i=0;i<n;i++){cin>>a[i];}cout<<"该数据的全排列:"<<endl;Perm(a,n,0);return 0;}《算法设计与分析》实验报告实验二递归与分治策略应用提高学号:**************姓名:*************班级:*************日期:2014-2015学年第1学期一、实验目的1、深入理解递归的概念和分治法的基本思想2、正确使用递归与分治策略设计相应的问题的算法3、掌握递归与分治算法时间空间复杂度分析,以及问题复杂性分析方法二、实验内容任务:从以下题目中任选一题完成,要求应用递归与分治策略设计解决方案。
《算法设计与分析》实验指导实验一分治与递归一、实验目的:1. 理解递归的概念。
2. 掌握设计有效算法的分治策略。
3. 掌握C++面向对象编程方法。
二、实验指导1. 分治法的总体思想求解一个复杂问题可以将其分解成若干个子问题,子问题还可以进一步分解成更小的问题,直到分解所得的小问题是一些基本问题,并且其求解方法是已知的,可以直接求解为止。
分治法作为一种算法设计策略,要求分解所得的子问题是同类问题,并要求原问题的解可以通过组合子问题的解来获取。
分治与递归像一对孪生兄弟,经常同时应用在算法设计之中,并由此产生许多高效的算法。
2. 分治法的基本步骤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,...,yk); //将各子问题的解合并为原问题的解}3. C++类定义例class Complex{public:Complex( ):real(0),imag(0) {} //构造函数Complex(double r,double i):real(r),imag(i) {} //构造函数Complex operator + (Complex c2); //重载“+”运算符operator double( ) //重载类型转换运算符{return real;}friend ostream& operator << (ostream&,Complex&); //重载流插入运算符“<<”private:double real;double imag;};三、实验内容及要求:在程序中创建一个学生对象数组并初始化数据,完成如下编程任务。
实验一我保证没有抄袭别人作业!1.实验题目必做:n 用分治思想设计实现二分搜索、合并排序,并且用不同数据量进行实验对比分析。
选做:阶乘(递归与分治)。
2.实验目的掌握设计算法的分治策略,通过实验学习分治策略设计技巧, 理解递归的概念验证二分搜索的时间复杂度。
掌握算法效率的分析和实验验证方法。
3.算法设计3.1 分治法基本思想将一个规模为n的问题分解为k个规模较小的子问题,这些子问题相互独立且与原问题相同。
然后递归的解这些子问题,然后将这些子问题的解合并得到原问题的解。
3.2二分搜索技术分解(devide):将n个元素分成个数大致相同的两半。
此时,原问题a[n]->子问题a[1,n/2]与a[2/n,n] 解决(conquer):取a[n/2]与欲查找的x作比较。
如果x=a[n/2],则找到x,算法终止。
如果x<a[n/2],则我们只要在数组a的左半部继续搜索x。
如果x>a[n/2],则我们只要在数组a的右半部继续搜索x。
合并(combine):此结果无需合并。
3.3合并排序分解(devide):将n个元素分成个数大致相同的两半。
此时,原问题a[n]->子问题a[1,n/2]与a[2/n,n] 解决(conquer):递归解n/2规模的子问题合并(combine):合并已排好序的两部分进行合并。
3.4快速排序分解(devide):找到基准元素,将数组分为三部分,两段。
此时,原问题a[p,r]->子问题a[p,q-1]、a[q]、a[q+1,r]。
解决(conquer):通过递归调用快速排序,对数组a[p,q-1]与a[q+1,r]进行排序。
合并(combine):此结果无需合并,因为子数组都是原址排序得,所以不需要合并操作。
3.5阶乘分解(devide):将n!分成n*(n-1)!,每次使其规模减少一。
解决(conquer):如果n=0,则输出结果1。
如果n=1,则输出结果1。
实验一递归与分治策略实验目的1.了解并掌握递归的概念,递归算法的基本思想;2.掌握分治法的基本思想方法;3.了解适用于用分治法求解的问题类型,并能用递归或非递归的方式设计相应的分治法算法;4.掌握分治法复杂性分析方法,比较同一个问题的递归算法与循环迭代算法的效率。
预习与实验要求1.预习实验指导书及教材的有关内容,掌握分治法的基本思想;2.严格按照实验内容进行实验,培养良好的算法设计和编程的习惯;3.认真听讲,服从安排,独立思考并完成实验。
实验原理简单说来,当一个函数用它自己来定义时就称为递归。
一般来说,递归需要有边界条件、递归前进段和递归返回段。
当边界条件不满足时,递归前进;当边界条件满足时,递归返回。
因此,在考虑使用递归算法编写程序时,应满足两点:1)该问题能够被递归形式描述;2)存在递归结束的边界条件。
递归的能力在于用有限的语句来定义对象的无限集合。
用递归思想写出的程序往往十分简洁易懂。
一般说来,一个递归算法可以转换称为一个与之等效的非递归算法,但转换后的非递归算法代码将成倍地增加。
分治是一种被广泛应用的有效方法,它的基本思想是把最初的问题分解成若干子问题,然后在逐个解决各个子问题的基础上得到原始问题的解。
所谓分治就是“分而治之”的意思。
由于分解出的每个子问题总是要比最初的问题容易些,因而分治策略往往能够降低原始问题的难度,或者提高解决原始问题的效率。
根据如何由分解出的子问题求出原始问题的解,分治策略又可分为两种情形:第一,原始问题的解只存在于分解出的某一个子问题中,则只需要在原始问题的一个划分中求解即可;第二,原始问题的解需要由各个子问题的解再经过综合处理得到。
无论是哪一种情况,分治策略可以较快地缩小问题的求解范围,从而加快问题求解的速度。
分治策略运用于计算机算法是,往往会出现分解出来的子问题与原始问题类型相同的现象,而与原问题相比,各个子问题的规模变小了,这刚好符合递归的特征。
因此分治策略往往是和递归联系在一起的。
《算法设计与分析》实验指导书计算机科学与技术学院石少俭实验一分治法1、实验目的(1)掌握设计有效算法的分治策略。
(2)通过快速排序学习分治策略设计技巧2、实验要求(1)熟练掌握分治法的基本思想及其应用实现。
(2)理解所给出的算法,并对其加以改进。
3、分治法的介绍任何一个可以用计算机求解的问题所需的计算时间都与其规模有关。
问题的规模越小,越容易直接求解,解题所需的计算时间也越少。
而当n较大时,问题就不那么容易处理了。
要想直接解决一个规模较大的问题,有时是相当困难的。
分治法的设计思想是,将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。
如果原问题可分割成k个子问题,1<k≤n ,且这些子问题都可解,并可利用这些子问题的解求出原问题的解,那么这种分治法就是可行的。
由分治法产生的子问题往往是原问题的较小模式,这就为使用递归技术提供了方便。
在这种情况下,反复应用分治手段,可以使子问题与原问题类型一致而其规模却不断缩小,最终使子问题缩小到很容易直接求出其解。
这自然导致递归过程的产生。
分治与递归像一对孪生兄弟,经常同时应用在算法设计之中,并由此产生许多高效算法。
分治法的适用条件(1)该问题的规模缩小到一定的程度就可以容易地解决;(2)该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质。
(3)利用该问题分解出的子问题的解可以合并为该问题的解;(4)该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子问题。
上述的第一条特征是绝大多数问题都可以满足的,因为问题的计算复杂性一般是随着问题规模的增加而增加;第二条特征是应用分治法的前提,它也是大多数问题可以满足的,此特征反映了递归思想的应用;第三条特征是关键,能否利用分治法完全取决于问题是否具有第三条特征,如果具备了第一条和第二条特征,而不具备第三条特征,则可以考虑贪心法或动态规划法。
第四条特征涉及到分治法的效率,如果各子问题是不独立的,则分治法要做许多不必要的工作,重复地解公共的子问题,此时虽然可用分治法,但一般用动态规划法较好。
分治策略算法实验报告引言分治策略是一种经典的算法设计策略,也是算法设计中最重要的思想之一。
其基本思想是将大问题划分成小的、相互独立的子问题,再将子问题合并求解,最终得到原问题的解。
本实验将通过实际例子,验证分治策略算法的有效性。
实验内容本实验选择两个经典的算法问题进行实现和验证,分别是二分查找和快速排序。
这两个问题在算法领域都有重要的应用价值,也是实践分治算法的好例子。
问题1:二分查找二分查找是一种在有序数组中查找特定元素的算法,其基本思想是将数组分为两部分,然后判断目标值在哪一部分,并且逐步缩小问题的规模。
具体实现如下:pythondef binary_search(arr, target):low = 0high = len(arr) - 1while low <= high:mid = (low + high) 2if arr[mid] == target:return midelif arr[mid] < target:low = mid + 1else:high = mid - 1return -1问题2:快速排序快速排序是一种高效的排序算法,其基本思想是通过一趟划分将待排序序列分割成两个独立的子序列,然后递归地对子序列进行排序,最终得到有序序列。
具体实现如下:pythondef quicksort(arr):if len(arr) <= 1:return arrpivot = arr[len(arr) 2]left = [x for x in arr if x < pivot]middle = [x for x in arr if x == pivot]right = [x for x in arr if x > pivot]return quicksort(left) + middle + quicksort(right)实验结果为了验证分治策略算法的有效性,我们分别对上述两个问题进行了测试。
算法分析与设计实验报告实验一分治策略排序一、实验目的1)以排序问题为例,掌握分治法的基本设计策略;2)熟练掌握合并排序算法的实现;3)熟练掌握快速排序算法的实现;4) 理解常见的算法经验分析方法。
二、算法思路1. 合并排序算法思想:分而治之(divide - conquer);每个递归过程涉及三个步骤第一, 分解: 把待排序的 n 个元素的序列分解成两个子序列, 每个子序列包括 n/2 个元素.第二, 治理: 对每个子序列分别调用归并排序MergeSort, 进行递归操作第三, 合并: 合并两个排好序的子序列,生成排序结果.最坏时间复杂度最好时间复杂度空间复杂度2.快速排序算法思想:通过一躺排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一不部分的所有数据都要小,然后再按次方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
假设要排序的数组是A[1]……A[N],首先任意选取一个数据(通常选用第一个数据)作为关键数据,然后将所有比它的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一躺快速排序。
一躺快速排序的算法是:1)、设置两个变量I、J,排序开始的时候I:=1,J:=N;2)以第一个数组元素作为关键数据,赋值给X,即X:=A[1];3)、从J开始向前搜索,即由后开始向前搜索(J:=J-1),找到第一个小于X的值,两者交换;4)、从I开始向后搜索,即由前开始向后搜索(I:=I+1),找到第一个大于X的值,两者交换;5)、重复第3、4步,直到I=J;三、实验内容:1. 准备实验数据要求:编写一个函数data-generate,生成2000个在区间[1,10000]上的随机整数,并将这些数输出到外部文件data.txt中。
这些数作为本算法实验的输入数据。
2. 实现合并排序算法要求:实现mergesort算法。
输入:待排数据文件data.txt;输出:有序数据文件resultsMS.txt(注:建议将此排好序的数据作为实验二的算法输入);程序运行时间TimeMS。
算法设计与分析实验指导书详解资料内容仅供您学习参考,如有不当之处,请联系改正或者删除算法设计与分析实验指导书东北大学软件学院2012年资料内容仅供您学习参考,如有不当之处,请联系改正或者删除1目录算法设计与分析 (1)实验指导书 (1)前言 (3)实验要求 (4)实验1 分治法的应用(2学时) (5)1.实验目的 (5)2.实验类型 (5)3.预习要求 (5)4.实验基本要求 (5)5.实验基本步骤 (7)实验2动态规划(2学时) (11)1.实验目的 (11)2.实验类型 (11)3.预习要求 (11)4.实验基本要求 (11)5.实验基本步骤 (12)实验3 回溯法(4学时) (17)1.实验目的 (17)2.实验类型 (17)3.预习要求 (17)4.实验基本要求 (17)5.实验基本步骤 (19)前言《算法设计与分析》是一门面向设计,处于计算机科学与技术学科核心地位的教育课程。
通过对计算机算法系统的学习,使学生理解和掌握计算机算法的通用设计方法,培养对算法的计算复杂性正确分析的能力,为独立设计算法和对算法进行复杂性分析奠定基础。
要求掌握算法复杂度分析、分治法、动态规划法、贪心法、回溯法、分支限界法等算法的设计方法及其分析方法。
能将这些方法灵活的应用到相应的问题中,并且能够用C++实现所涉及的算法,并尽量做到低复杂度,高效率。
通过本课程的实验,使学生加深对课程内容的理解,培养学生严密的思维能力,运用所学知识结合具体问题设计适用的算法的能力;培养学生良好的设计风格,激励学生创造新算法和改进旧算法的愿望和热情。
希望同学们能够充分利用实验条件,认真完成实验,从实验中得到应有的锻炼和培养。
希望同学们在使用本实验指导书及进行实验的过程中,能够帮助我们不断地发现问题,并提出建议,使《算法设计与分析》课程成为对大家有益的课程。
实验要求《算法设计与分析》课程实验的目的是为了使学生在课堂学习的同时,通过一系列的实验,使学生加深理解和更好地掌握《算法设计与分析》课程教学大纲要求的内容。
《算法设计与分析》课程实验报告姓名:班级:学号:学期:指导教师:实验名称:分治策略—二分查找与快速排序实验时间:2020 年 5 月8 日第10 周星期四成绩评定:1、实验目的1.掌握分治策略的基本思想并会用其解决一些问题2.掌握二分查找和快速排序算法2、软硬件环境1.操作系统:windows102.编写环境:DEV—C++3.编程语言:c3、实验内容1.二分查找①二分查找算法:二分查找(折半查找):查找数组中是否包含指定元素。
如果包含指定元素,则返回指定元素的index(从0开始);如果不包含指定元素,则返回-1;前提:数组中的元素必须是有序的。
原理:将被查找的数组分为三部分,依次是中值前、中值、中值后,将指定元素和数组的中值进行比较,如果指定元素小于中值则在(中值前)中找,如果指定元素大于中值则在(中值后)中找,如果指定元素等于中值则直接返回。
依次查找后,如果不包含指定元素,则返回-1;注:中值即数组中间位置的值。
②二分查找时间复杂度:O(log2n)2为底数2.快速排序①快速排序:快速排序是对冒泡排序的一种改进。
快速排序基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
快排实现的本质也和所有的其他的分治算法一样,包含了分解子问题,解决子问题,将子问题合并这三个步骤。
②时间复杂度:O(nlogn)③空间复杂度:O(nlogn)4、实验步骤1.回顾分治策略的思想2.回顾二分查找和快排算法3.调试编写环境4.编写程序5.测试程序5、实验结果(包括程序运行结果、实测数据结果、数据分析、实验结论等)1.二分查找2.快排实验名称:实验时间:年月日第周星期成绩评定:1、实验目的2、软硬件环境3、实验内容4、实验步骤5、实验结果(包括程序运行结果、实测数据结果、数据分析、实验结论等)实验名称:实验时间:年月日第周星期成绩评定:1、实验目的2、软硬件环境3、实验内容4、实验步骤5、实验结果(包括程序运行结果、实测数据结果、数据分析、实验结论等)。
合肥师范学院实验报告册2016/ 2017 学年第 1 学期系别计算机学院实验课程算法设计与分析专业软件工程班级一班姓名杨文皇学号1310421071指导教师程敏实验一:分治算法一、实验目的1、理解分治策略的基本思想;2、掌握用分治法解决问题的一般技巧。
二、实验内容利用分治算法在含有n个不同元素的数组a[n]中同时找出它的最大的两个元素和最小的两个元素,编写出完整的算法,并分析算法的时间复杂度。
三、实验源程序。
1、算法设计思想利用分治法思想,n个不同元素的数组不断进行划分,化为若干个个子问题,其与原问题形式相;解决子问题规模较小而容易解决则直接解决:即当n的规模为只有一个或两个,三个或四个;否则再继续直至更小的子问题:即当n的规模大于四时。
将已求得的各个子问题的解,逐步合并原问题的解:即将左右两边求得的子问题进行比较,在四个数据中的得到两个最大(最小)值。
为了简化空间,采用了对每一个小规模问题的排序,以及合并原问题时,对四个数据进行排序,获得当前或合并的最大(最小)值2、算法实现#include<iostream>using namespace std;int a[10]={4,5,6,2,3,9,8,13,1};int b[4];int sort(int i,int j){int temp,k;for(;i<j;i++){for(k=i;k<j;k++)if(a[k]>a[k+1]){temp=a[k];a[k]=a[k+1];a[k+1]=temp;}}return 0;}int sort1(int lmin1,int lmin2,int rmin1,int rmin2){int i,j,temp;b[0]=lmin1;b[1]=lmin2;b[2]=rmin1;b[3]=rmin2;for(i=0;i<=1;i++)for(j=i;j<=3;j++){if(b[i]>b[j]){temp=b[i];b[i]=b[j];b[j]=temp;}}return 0;}int maxmin(int i,int j,int &fmin1,int &fmin2,int &fmax1,int &fmax2) {int mid;int lmin1,lmin2,lmax1,lmax2;int rmin1,rmin2,rmax1,rmax2;if(i==j || i==j-1){sort(i,j);fmin1=a[i];fmin2=a[i];fmax1=a[j];fmax2=a[j];}elseif(i==j-2 || i==j-3){sort(i,j);fmin1=a[i];fmin2=a[i+1];fmax1=a[j-1];fmax2=a[j];}else{mid=(i+j)/2;maxmin(i,mid,lmin1,lmin2,lmax1,lmax2);maxmin(mid+1,j,rmin1,rmin2,rmax1,rmax2);sort1(lmin1,lmin2,rmin1,rmin2);fmin1=b[0];fmin2=b[1];sort1(lmax1,lmax2,rmax1,rmax2);fmax1=b[2];fmax2=b[3];}return 0;}int main(){int fmin1,fmin2,fmax1,fmax2;int i;maxmin(0,8,fmin1,fmin2,fmax1,fmax2);cout<<endl;cout<<"该组数据为:";for(i=0;i<=8;i++)cout<<a[i]<<" ";cout<<endl<<endl<<"最小值是:"<<fmin1<<",第二小值是:"<<fmin2<<endl;cout<<endl<<"第二大值是:"<<fmax1<<",最大值是:"<<fmax2<<endl<<endl;return 0;}3、程序结果4、算法分析用T(n)元素表示数,则导出的递推关系式是:在理想的情况下,即每一小规模的子问题中的数据都是递增序列,则:当n<=4时,T(n)=1; 当n>4时,T(n)= T(n/2)+ T(n/2)(均向下取整);在非理想情况下,即每一小规模的子问题中的数据都是递减序列,则:当n=1时,T(n)=1;当n=2时,T(n)=2;当n=3时,T(n)=3;当n=4时,T(n)=6;当n>4时,T(n)= T(n/2)+ T(n/2)(均向下取整)+12。
分治策略的实验报告1. 引言分治策略是一种问题解决方法,通过将问题分解为更小的子问题,并通过解决这些子问题来解决原始问题。
该策略在计算机科学中具有广泛应用,特别是在算法设计和优化中。
本实验旨在通过实际应用和测试分治策略,深入了解其原理及实际效果。
2. 实验目标本实验的主要目标包括:- 理解分治策略的基本原理和应用场景;- 设计并实现一个分治算法;- 分析和比较分治策略与其他解决方法的性能。
3. 实验方法3.1 实验工具和环境本实验使用的工具和环境如下:- 编程语言:Python;- 开发工具:Jupyter Notebook;- 硬件环境:Intel Core i7处理器,8GB内存。
3.2 实验步骤本实验采用以下步骤进行:1. 研究分治策略的理论知识,了解其基本思想和优势;2. 选择一个适用于分治策略的问题,并设计分治算法;3. 使用Python编程语言实现该分治算法;4. 随机生成一组用于测试的输入数据,包括不同规模和特征的数据;5. 分别用分治策略和其他解决方法解决该问题,并对比它们的性能;6. 分析实验结果,并总结得出结论。
4. 实验结果4.1 算法设计在本实验中,选择了经典的快速排序算法作为分治策略的例子。
快速排序基于分治的思想,通过将一个序列分成两个子序列,分别对它们进行排序,最后将这两个子序列合并起来。
具体的算法步骤如下:1. 选择一个枢纽元素(pivot),将序列分为两部分,使得左边的元素小于等于pivot,右边的元素大于pivot;2. 对分割出来的左、右两个子序列递归地进行快速排序;3. 合并左、右两个有序子序列即可得到排序后的序列。
函数实现伪代码如下:pythondef quick_sort(arr):if len(arr) <= 1:return arrpivot = arr[0]left = [x for x in arr[1:] if x <= pivot]right = [x for x in arr[1:] if x > pivot]return quick_sort(left) + [pivot] + quick_sort(right)4.2 性能测试为了测试快速排序算法在不同规模数据上的性能表现,生成了一组包含10000个随机整数的序列,并分别用快速排序算法和Python自带的排序函数进行排序,并比较它们的执行时间。
本科实验报告课程名称:算法设计与分析实验项目:递归与分治算法实验地点:计算机系实验楼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.递归式,就是如何将原问题划分成子问题。
算法设计中的分治与回溯策略算法设计中的分治与回溯策略是两种常用的问题解决方法,它们在解决复杂问题时具有重要的作用。
本文将介绍分治与回溯策略的基本概念和应用场景,并通过实例详细探讨它们的具体应用。
一、分治策略分治策略是一种将问题划分为更小的子问题,并通过在子问题上递归地应用相同的方法来解决原问题的方法。
它包含以下三个基本步骤:1. 分解(Divide):将原问题分解为若干个规模较小且相互独立的子问题。
2. 解决(Conquer):递归地解决每个子问题,如果子问题的规模足够小,则直接求解。
3. 合并(Combine):将子问题的解合并为原问题的解。
分治策略的经典应用是归并排序和快速排序。
以归并排序为例,其思想是将待排序的序列划分为若干个子序列,分别进行排序,然后将排好序的子序列合并成最终有序序列。
这个过程中,分解步骤是通过将序列划分为两个子序列,解决步骤是递归地对子序列进行排序,合并步骤是将排好序的子序列合并。
二、回溯策略回溯策略是一种通过穷举所有可能的解并逐步构建可行解的方法。
它通常用于求解组合优化问题、排列问题和搜索问题。
回溯法的基本思想如下:1. 选择(Choose):在每一步选择中,我们都有多个选择可以进行尝试。
2. 约束(Constraint):对选择进行约束条件的限制,以排除不满足要求的选择。
3. 撤销(Un-choose):如果发现当前选择并不是正确的解,可以撤销上一步或几步的选择,进行其他尝试。
回溯策略经常使用递归来实现,其关键是正确地定义选择、约束和撤销的操作。
回溯法可以通过剪枝操作来减少搜索空间,提高求解效率。
回溯策略的一个典型应用是八皇后问题。
八皇后问题是要求在一个8×8的棋盘上放置8个皇后,使得任意两个皇后都不能相互攻击。
回溯法通过逐行放置皇后,并检查每个位置是否满足约束条件,如果满足则进入下一行继续放置,如果不满足则进行回溯,尝试其他选择。
结语分治策略和回溯策略都是算法设计中常用的解决复杂问题的方法。
《算法设计与分析》实验报告分治策略姓名:XXX专业班级:XXX学号:XXX指导教师: XXX完成日期:XXX一、试验名称:分治策略(1)写出源程序,并编译运行(2)详细记录程序调试及运行结果二、实验目的(1)了解分治策略算法思想(2)掌握快速排序、归并排序算法(3)了解其他分治问题典型算法三、实验内容(1)编写一个简单的程序,实现归并排序。
(2)编写一段程序,实现快速排序。
(3)编写程序实现循环赛日程表。
设有n=2k个运动员要进行网球循环赛。
现要设计一个满足以下要求的比赛日程表:(1)每个选手必须与其它n—1个选手各赛一次(2)每个选手一天只能赛一场(3)循环赛进行n—1天四、算法思想分析(1)编写一个简单的程序,实现归并排序.将待排序元素分成大小大致相同的2个子集合,分别对2个子集合进行排序,最终将排好序的子集合合并成为所要求的排好序的集合.(2)编写一段程序,实现快速排序。
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
(3)编写程序实现循环日赛表。
按分治策略,将所有的选手分为两组,n个选手的比赛日程表就可以通过为n/2个选手设计的比赛日程表来决定。
递归地用对选手进行分割,直到只剩下2个选手时,比赛日程表的制定就变得很简单。
这时只要让这2个选手进行比赛就可以了。
五、算法源代码及用户程序(1)编写一个简单的程序,实现归并排序。
#include<iostream>#include<time。
h〉#define MAX 10using namespace std;void merge(int array[],int p,int q,int r){int i,k;int begin1,end1,begin2,end2;int*temp = new int[r-p+1];begin1 = p;end1 = q;begin2 = q+1;end2 = r;k = 0;while((begin1 <= end1)&&(begin2 <= end2)){if(array[begin1]< array[begin2]){temp[k] = array[begin1];begin1++;}else{temp[k]= array[begin2];begin2++;}k++;}while(begin1 <= end1){temp[k++] = array[begin1++];}while(begin2 <= end2){temp[k++] = array[begin2++];}for(i = 0;i < (r-p+1);i++){array[p+i] = temp[i];}delete[](temp);}void merge_sort(int data[],int left,int right){if(left 〈right){int mid = (left + right)/2;merge_sort(data,left,mid);merge_sort(data,mid + 1,right);merge(data,left,mid,right);}}void main(){int number[MAX] = {0};srand(time(NULL));printf(”排序前:");for(int i = 0;i 〈MAX; i++){number[i] = rand() % 100;printf(”%d ”, number[i]);}cout〈<endl;merge_sort(number,0,9);printf("排序后:");for(int j = 0;j < MAX;j++){printf(”%d ”,number[j]);}}(2)编写一段程序,实现快速排序。
算法分析与设计实验报告第 1次实验附录:完整代码#include <time.h>#include <iostream>#include <iomanip>#include <fstream>using namespace std;voidmax_min(int *array,intl,intr,int&nmax,int&nmin) {if(l==r)//数组只有一个元素时{nmax = array[l];nmin = array[l];return;}if(l+1 == r)//数组有两个元素时,比较大小并赋值 {if(array[l]>=array[r]){nmax = array[l];nmin = array[r];return ;}else if(array[l]<array[r]){nmax = array[r];nmin = array[l];return ;}}int m = (l+r)/2;intrmax,rmin;max_min(array,l,m,rmax,rmin);//递归求左边的最小值intlmax,lmin;max_min(array,m,r,lmax,lmin);//递归求右边的最大值nmax = max(lmax,rmax);nmin = min(lmin,rmin);}int main (){inti,j=0;double k=0.0;clock_tstart,end,over;start=clock();end=clock();over=end-start;start=clock();//my testofstreamfout("b.txt");int r;for(int bb=0;bb<=100000;bb++){r = rand();//cout<< r<<endl;fout<< r <<endl;}fout.close();int a[100000];ifstream fin("b.txt");intdd,Datalen=-1;while( ! fin.eof() ){//cout<<a[Datalen]<<endl;Datalen++;fin>>a[Datalen];}fin.close();intmnum,nnum;max_min(a,0,Datalen,mnum,nnum);cout<<mnum<<","<<nnum<<endl;end=clock();printf("The time is %6.3f",(double)(end-start-over)/CLK_TCK); system("pause");return 0;}。
题目:用分治法实现一组无序序列的两路合并排序和快速排序以及其它排序算法。
程序代码#include<iostream>using namespace std;#include<time.h>#include<algorithm>#include<stdlib.h>#include <cstdio>#include <cstring>#include<windows.h>#include<Mmsystem.h>#define random(x) (rand()%x)#define NUM 100000clock_t start,stop;double duration;//简单选择排序void SelectSort(int A[],int n){int small;for(int i =0;i<n-1;i++){small = i;for(int j = i+1;j<n;j++){if(A[j]<A[small])small = j;swap(A[i],A[small]);}}}//直接插入排序void InsertSort(int A[],int n){for(int i=1;i<n;i++){int j=i;int temp=A[j];while(j>0&&temp<A[j-1]){A[j]=A[j-1];j--;}A[j]=temp;}}//冒泡排序void BubbleSort(int A[],int n){int i,j,last;i=n-1;while(i>0){last=0;for(j=0;j<i;j++)if(A[j+1]<A[j]){swap(A[j],A[j+1]);last=j;}i=last;}}void QSort(int A[],int left,int right){int i,j;if(left<right){i=left;j=right+1;do{do i++;while (A[i]<A[left]);do j--;while (A[j]>A[left]);if(i<j)swap(A[i],A[j]);}while(i<j);swap(A[left],A[j]);QSort(A,left,j-1);QSort(A,j+1,right);}}//快速排序void QuickSort(int A[],int n){QSort(A,0,n-1);}void GQSort(int A[],int left,int right) {int i,j;if(right>=9){if(left<right){i=left;j=right+1;do{do i++;while (A[i]<A[left]);do j--;while (A[j]>A[left]);if(i<j)swap(A[i],A[j]);}while(i<j);swap(A[left],A[j]);QSort(A,left,j-1);QSort(A,j+1,right);}}else{InsertSort(A,right-left+1);return ;}}//改进的快速排序void GQuickSort(int A[],int n){GQSort(A,0,n-1);}//两路合并排序void Merge(int A[],int i1,int j1,int i2,int j2) {int* Temp=new int[j2-i1+1];int i=i1,j=i2,k=0;while(i<=j1&&j<=j2){if(A[i]<=A[j])Temp[k++]=A[i++];else Temp[k++]=A[j++];}while (i<=j1)Temp[k++]=A[i++];while(j<=j2)Temp[k++]=A[j++];for(i=0;i<k;i++)A[i1++]=Temp[i];delete[] Temp;}void MergeSort(int A[],int n){int i1,j1,i2,j2;int size=1;while(size<n){i1=0;while(i1+size<n){i2=i1+size;j1=i2-1;if(i2+size-1>n-1)j2=n-1;elsej2=i2+size-1;Merge(A,i1,j1,i2,j2);i1=j2+1;}size*=2;}}//堆排序void AdjustDown(int A[],int r,int j){int child=2*r+1;int temp=A[r];while (child<=j){if((child<j)&&(A[child]<A[child+1]))child++;if(temp>=A[child])break;A[(child-1)/2]=A[child];child=2*child+1;}A[(child-1)/2]=temp;}void HeapSort(int A[],int n){for(int i=(n-2)/2;i>-1;i--)AdjustDown(A,i,n-1);for(int i=n-1;i>0;i--){swap(A[0],A[i]);AdjustDown(A,0,i-1);}}void Output(int A[],int n){for(int i = 0;i < n;i ++){printf("%d ",A[i]);}}void TimeOfSelectSort(int A[],int n){//SelectSortstart = clock();//start = timeGetTime();SelectSort(A,n);stop = clock();//stop = timeGetTime();//printf("\nThe List after SelectSort is:\n");//Output(a,NUM);printf("The time of SelectSort is:\n");duration = (double)(stop-start)/(CLOCKS_PER_SEC); //强制类型转换printf("%f",duration);//cout<<duration<<endl;}void Menu(){//system("cls");printf("\n\nThe menu of sort algorithm is:\n\n");printf("1. SelectSort\n");printf("2. InsertSort\n");printf("3. BubbleSort\n");printf("4. QuickSort\n");printf("5. MergeSort\n");printf("0. Exit\n");printf("\n\nPlease choose the sort algorithm:");}int main(){int *a,*b,*c,*d,*e,*f,*g,choose;//long long NUM;//printf("Please enter the size of List:");//scanf("%lld",&NUM);a = (int*)malloc(NUM * sizeof(int));b = (int*)malloc(NUM * sizeof(int));c = (int*)malloc(NUM * sizeof(int));d = (int*)malloc(NUM * sizeof(int));e = (int*)malloc(NUM * sizeof(int));f = (int*)malloc(NUM * sizeof(int));g = (int*)malloc(NUM * sizeof(int));/*//不用malloc的话,随机生成100000个数时,会出现停止运行int a[NUM];//乱序int b[NUM];int c[NUM];int d[NUM];//乱序int e[NUM];int f[NUM];int g[NUM];//乱序*/memset(a,0,sizeof(a));memset(b,0,sizeof(b));memset(c,0,sizeof(c));memset(d,0,sizeof(d));memset(e,0,sizeof(e));memset(f,0,sizeof(f));memset(g,0,sizeof(g));srand((int)time(0));for(int x = 0;x < NUM;x ++){a[x]=random(NUM);b[x]=a[x];c[x]=a[x];d[x]=a[x];e[x]=a[x];f[x]=a[x];g[x]=a[x];//cout<<a[x]<<endl;}//Outputprintf("\nThe initial List is:\n");Output(a,NUM);Menu();scanf("%d",&choose);switch(choose){case 1://SelectSort(a,NUM);//Output(a,NUM);start = clock();SelectSort(a,NUM);stop = clock();Output(a,NUM);//printf("\nThe List after SelectSort is:\n");//Output(a,NUM);printf("\n\nThe time of SelectSort is:\n");duration = (double)(stop-start)/(CLOCKS_PER_SEC);printf("%f",duration);break;case 2:InsertSort(a,NUM);Output(a,NUM);start = clock();InsertSort(b,NUM);stop = clock();//printf("\nThe List after SelectSort is:\n");//Output(a,NUM);printf("\n\nThe time of InsertSort is:\n");duration = (double)(stop-start)/(CLOCKS_PER_SEC);printf("%f",duration);break;case 3:BubbleSort(a,NUM);Output(a,NUM);start = clock();BubbleSort(c,NUM);stop = clock();//printf("\nThe List after SelectSort is:\n");//Output(a,NUM);printf("\nThe time of BubbleSort is:\n");duration = (double)(stop-start)/(CLOCKS_PER_SEC);printf("%f",duration);break;case 4:QuickSort(a,NUM);Output(a,NUM);start = clock();QuickSort(d,NUM);stop = clock();//printf("\nThe List after SelectSort is:\n");//Output(a,NUM);printf("\nThe time of QuickSort is:\n");duration = (double)(stop-start)/(CLOCKS_PER_SEC);printf("%f",duration);break;case 5:MergeSort(a,NUM);Output(a,NUM);start = clock();MergeSort(f,NUM);stop = clock();//printf("\nThe List after SelectSort is:\n");//Output(a,NUM);printf("\nThe time of MergeSort is:\n");duration = (double)(stop-start)/(CLOCKS_PER_SEC);printf("%f",duration);break;case 0:printf("Wrong Input\n");break;}return 0;}实验结果测试数据:随机生成100000个数据。