分治法实验报告

合集下载

分治算法实验

分治算法实验

分治算法实验(用分治法查找数组元素的最大值和最小值)算法分析与设计实验报告第一次实验实验步骤关键代码}else//当数组中元素个数少于2时,直接赋值处理1. 先解决小规模的问题,如数组中只有1个元素或者只有两个元素时候的情况。

2. 将问题分解,如果数组的元素大于等于3个,将数组分为两个小的数组。

3. 递归的解各子问题,将中分解的两个小的数组再进行以上两个步骤最后都化为小规模问题。

4. 将各子问题的解进行比较最终得到原问题的解。

//分治法处理整个数组,求出最大值与最小值void merge( int a[], int left, int right, int &Max, int &Min){int max1=0,min 1=0,max2=0,min2=0;if (right-left>2) //当数组中元素个数大于3时,才实行分治法{int mid=(right+left)/2;merge(a,left,mid,max1,mi n1);//左半边递归调用自身,求岀最大值与最小值,分别保存在max1,min1中merge(a,mid+1,right,max2,mi n2);//右半边递归调用自身,求岀最大值与最小值,分别保存在max2,min2中if (max1>=max2)Max=max1; //子序列两两合并,求岀最大值与最小值elseMax=max2; //分别保存在Max与Minif (min1<=min2)Min=mi n1;elseMin=mi n2;测试结果实验心得Max=compmax(a,left,right);Min=compmi n( a,left,right);}}利用分治法(递归实现):非递归实现:请输入数据克1000093 32767The tine is1990003276? 9The tine is1000032767 0TJ IE tine is1000 32767 9The time is3276? RThe tine is內.0060-004TO通解,明白了分治法到底是怎样的一个过程,在代码实现分治法的时候,也使我加深了对于自己构造函数的理解,明白了分治法利用代码是怎样实现的,以及构造函数的传参与返回值等等地方需要注意的F;\鮒实验沁[p || B附录:完整代码(分治法)#include <iostream>#inelude <time.h>#include <iomanip> using namespacestd;//当数组中的元素个数小于3时,处理最大值int compmax(int A[], int start, int end) {int max;if (start<end) //有两个元素{if (A[start]<=A[end]) max=A[e nd];elsemax=A[start];}else //有一个元素max=A[start];return max;}//当数组中元素的个数小于2时,处理最小值int compmin(int A[], int start, int end){int min;if (start<end) //有两个元素{if (A[start]<=A[end]) mi n= A[start];elsemin= A[e nd];}else //有一个元素mi n=A[start];return mi n;}//分治法处理整个数组,求最大值与最小值void merge( int a[], int left, int right, int &Max,int &Min) 〃Max,Min 用来保存最大值与最小值//之所以使用&引用,是由于如果只是简单的使用变量,并不会改变Ma>与Min的值,使用指针也可以{int max1=0,min 1=0,max2=0,min2=0;if (right-left>2) //当数组中元素个数大于等于3时,进行分治{int mid=(right+left)/2;merge(a,left,mid,max1,min1); //左半边递归调用自身,求出最大值最小值,分别保存在max1,min1中merge(a,mid+1,right,max2,min2); //右半边递归调用自身,求出最大值最小值,分别保存在max2,min2中if (max1>=max2) //子序列两两合并,求出最大值与最小值,保存在Max与Mi n 中Max=max1;elseMax=max2;if (min 1<=min2)Min=min1;elseMin=min 2;}else //数组中元素个数小于3时的情况,直接赋值{Max=compmax(a,left,right);Mi n=compmi n( a,left,right);}}void ran( int *input, int n) //随机生成数组元素函数{int i;sran d(time(0)); for(i=0;i<n;i++) input[i]=ra nd();input[i]= '\0';}int a[1000000]; //定义全局变量用来存放要查找的数组int main(){int n;int i;int max;int min;coutvv "请输入要查找的序列个数:"<<e ndl;for (i=0;i<5;i++){cin>>n;ran (a,n);start=clock();en d=clock();over=end-start;start=clock();//调用分治法算法merge(a,0, n-1,max,min);coutvvmax<<‘ " vvminvvendl;en d=clock();printf( "The time is %6.3f" ,( double )(end-start-over)/CLK_TCK); //显示运行时间}system( "pause"); // 停止运行窗口return 0;}完整代码(非递归方法)#include <iostream>#include <time.h>#include <iomanip> usingnamespacestd;void ran( int *input, int n) {//随机生成数组元素函数int i;sran d(time(0));for (i=0;i<n;i++)in put[i]=ra nd();input[i]= '\0';}int a[1000000];int main(){int max=a[0],min=a[0];int i,j,n;cout<<"请输入数据规模: "<<e ndl;for (j=0;j<5;j++){cin»n;ran( a, n);clock_t start,e nd,over;//计算程序运行时间的算法start=clock();en d=clock();start=clock(); for(i=1;i<n;i++) {if (a[i]>max)max=a[i];if (a[i]<min) min=a[i];}coutvvmax<<‘ " vvminvvendl;en d=clock();printf( "The time is %6.3f" ,( double )(end-start-over)/CLK_TCK); // 显示运行时间}system( "pause");return 0;}。

分治算法的实验报告

分治算法的实验报告

一、实验背景分治算法是一种常用的算法设计方法,其基本思想是将一个复杂问题分解成若干个相互独立的小问题,然后将小问题递归求解,最终将子问题的解合并为原问题的解。

分治算法具有高效性、可扩展性和易于实现等优点,被广泛应用于各个领域。

本实验旨在通过实现分治算法解决实际问题,掌握分治算法的设计思想,并分析其时间复杂度。

二、实验目的1. 理解分治算法的基本思想;2. 掌握分治算法的递归实现方法;3. 分析分治算法的时间复杂度;4. 应用分治算法解决实际问题。

三、实验内容本实验选择两个分治算法:快速排序和合并排序。

1. 快速排序快速排序是一种高效的排序算法,其基本思想是将待排序序列分为两个子序列,其中一个子序列的所有元素均小于另一个子序列的所有元素,然后递归地对两个子序列进行快速排序。

(1)算法描述:① 选择一个基准值(pivot),通常取序列的第一个元素;② 将序列分为两个子序列,一个子序列包含所有小于基准值的元素,另一个子序列包含所有大于基准值的元素;③ 递归地对两个子序列进行快速排序。

(2)代码实现:```cvoid quickSort(int arr[], int left, int right) {if (left < right) {int pivot = arr[left];int i = left;int j = right;while (i < j) {while (i < j && arr[j] >= pivot) {j--;}arr[i] = arr[j];while (i < j && arr[i] <= pivot) {i++;}arr[j] = arr[i];}arr[i] = pivot;quickSort(arr, left, i - 1);quickSort(arr, i + 1, right);}}```2. 合并排序合并排序是一种稳定的排序算法,其基本思想是将待排序序列分为两个子序列,分别对两个子序列进行排序,然后将排序后的子序列合并为一个有序序列。

分治法实验报告

分治法实验报告

一. 实验目的及实验环境实验目的:熟练掌握运用分治法解决问题。

实验环境:windows下的Ubuntu虚拟机二. 实验内容利用分治法求一个数组的最大值、最小值(要求:数组的大小和数组的长度随机产生)三.方案设计分治法解决问题就是要将原问题分解成小问题,再将小问题分解成更小的问题,以此类推,直到最终分解的问题能够一步解决即可。

代码要求最后要输出数组的最大值、最小值。

所以,在用分治法求最值的函数max_min()中,需要将设置参数int *max,int *min。

即void max_min(int a[],int m,int n,int *max,int *min)。

这样就可以直接得到最大值、最小值。

该函数使用递归来实现,而递归的终止条件是最后分得的数组中只有一个或两个元素,当分得的数组元素个数大于2时,就进行递归调用。

四.测试数据及运行结果正确的3组运行结果:出现的错误:若将代码中的随机数函数返回值的类型改变,则会出现错误结果,甚至编译不通过。

五.总结1.实验过程中遇到的问题及解决办法;实验过程中,用分治法求最大值、最小值时,如果用返回值求最大值和最小值,则需要两个函数。

这样就会导致代码冗余,不会达到代码的复用性功能。

所以要将两个功能用一个函数直接实现就可以使用参数指针的形式。

2.对设计及调试过程的心得体会。

算法设计的课内实验既要实现实验的功能,还要讲究代码中算法的精妙、简单以及它的效率。

不能同其他高级语言的课内实验一样仅仅考虑如何完成该实验的功能,这样就可以真正地体验到算法与设计这门课的意义。

平时做实验时我们可以用不同算法实现,这样不仅可以积累平常上课学到的知识,还可以为以后的算法设计能力奠定基础。

平常更多地进行思考,可以让我们在求职时更受益。

六.附录:源代码(电子版)#include<stdio.h>#include<stdlib.h>#include<time.h>void max_min(int a[],int m,int n,int *max,int *min){int middle,hmax,hmin,gmax,gmin;if(m==n){ *max=a[m];*min=a[m];}else if(m==n-1){if(a[m]>a[n]){*max=a[m];*min=a[n];}else{*max=a[n];*min=a[m];}}else{max_min(a,m,middle,&gmax,&gmin);max_min(a,middle+1,n,&hmax,&hmin);if(gmax>hmax)*max=gmax;else*max=hmax;if(gmin<hmin)*min=gmin;else*min=hmin;}}int main(){int i;int max,min;srand((unsigned)time(NULL));int n=rand()%10+1;printf("数组的个数:%d\n",n);int a[n];for(i=0;i<n;i++){a[i]=rand()%50+1;printf("%d\t",a[i]);}max_min(a,0,n-1,&max,&min);printf("最大数:%d,最小数:%d\n",max,min);retur n 0;}。

分治算法实验报告

分治算法实验报告

算法分析与设计实验报告第 1 次实验if(maxi>maxj)max=maxi;elsemax=maxj;if(mini<minj)min=mini;elsemin=minj;return;}}srand((unsigned int)time(NULL));cout <〈”随机产生的数据(0—100):”;for(int i=0; i〈m; i++)a[i] = rand()%100;测试结果附录:完整代码SelectMaxMin.cpp:#include <iostream>#include <ctime>#include 〈cstdio>#include <iomanip>#include 〈cstdlib〉using namespace std;void SelectMaxMin(int *a,int i,int j,int &max,int &min) {if(i==j){max= a[i];min =a[i];return;}else{int mid=(i+j)/2;int maxi,maxj,mini,minj;SelectMaxMin(a,i,(i+j)/2,maxi,mini);SelectMaxMin(a,((i+j)/2)+1,j,maxj,minj);if(maxi〉maxj)max=maxi;elsemax=maxj;if(mini<minj)min=mini;elsemin=minj;return;}}int main(){clock_t start,end,over;start=clock();end=clock();over=end—start;start=clock();//freopen("in。

txt",”r",stdin);//freopen(”out。

txt”,”w",stdout);int m;cout 〈<"Please input the number : ”;cin>〉 m;int a[m];srand((unsigned int)time(NULL));cout 〈〈 "随机产生的数据(0-100):";for(int i=0; i〈m; i++)a[i] = rand()%100;for(int i=0; i〈m; i++)cout <〈 a[i] 〈< " ";cout 〈< endl;int max,min;SelectMaxMin(a,0,m-1,max,min);cout 〈< "max = " 〈〈 max 〈〈 endl;cout <〈”min = " <〈 min 〈〈 endl;end=clock();printf(”The time is %6.3f”,(double)(end-start—over)/CLK_TCK); }。

矩阵乘法分治法

矩阵乘法分治法
这样就将2个n阶矩阵的乘积变成计算8个n/2阶矩阵的乘积和4个n/2阶矩阵的加法。
当n=1时,2个1阶方阵的乘积可直接算出,只需要做一次乘法。当子矩阵阶n>1时,为求两个子矩阵的乘积,可继续对两个子矩阵分块,直到子矩阵的阶为1。由此,便产生了分治降阶的递归算法。
但是这个算法并没有降低算法的时间复杂度。由strassen矩阵乘法,
算法设计与分析实验报告
实验名称:矩阵乘法(分冶法)
一、问题陈述和分析:
1.实验目的:掌握分总冶策略的基本思想以及用分冶法解决问题的一般技巧.运用编程工具,并运用分冶法来解* n阶矩阵,求它们两的乘积矩阵C。这里,假设n是2的幂次方;
3.实验要求:编制程序并对其时间复杂度和空间复杂度进行分析.
4.voidAdd(int n,int **A,int **B,int **C)
函数的功能是:实现C=A+B,A,B,C都是n*n矩阵。
3.voidMul(int n,int **A,int **B,int **M)
函数的功能是:将n*n的矩阵A,B相乘,结果存放在n*n的矩阵M中。
算法设计:
整个算法的大致思想是:在函数Mul(int n,int **A,int **B,int **M)中先判断n的值,若n==1,表示A,B,C均为一阶方阵。则M[0][0]=A[0][0]*B[0][0];否则,调用Divide(n,A,A11,A12,A21,A22);和Divide(n,B,B11,B12,B21,B22);将A和B都分为四个(n/2)*(n/2)的子矩阵。然后递归调用
正确性证明:
由矩阵乘法的计算方法可知,上述计算方法显然正确
三、时间和空间复杂性分析:
时间复杂性:
Strassen矩阵乘法中,用了7次对于n/2阶矩阵乘法的递归调用和18次n/2阶矩阵的加减运算。由此可知,该算法所需的计算时间T(n)满足如下递归方程

分治法实验心得

分治法实验心得

分治法实验心得分治法实验心得分治法是一种常见的算法设计策略,它将原问题划分成若干个规模较小但结构与原问题相似的子问题,然后递归地求解这些子问题,最终将子问题的解合并得到原问题的解。

在本次实验中,我们实现了两个基于分治法的算法:归并排序和快速排序,并对它们进行了性能测试和比较。

一、归并排序1. 原理归并排序是一种典型的分治算法。

它将待排序数组不断地二分为两个子数组,直到每个子数组只剩下一个元素。

然后将相邻的两个子数组合并成一个有序数组,再将相邻的两个有序数组合并成一个更大的有序数组,直到最终合并成整个待排序数组。

2. 实现我们采用了自顶向下的递归方式实现了归并排序。

具体来说,我们定义了一个merge函数用于合并两个有序子数组,并定义了一个sort 函数用于递归地对左右两个子数组进行排序和合并。

3. 性能测试与比较我们使用Python内置的time模块对不同规模(10^2 ~ 10^6)的随机整数列表进行了性能测试,并绘制出了运行时间随数组规模增大的变化曲线。

结果表明,归并排序的时间复杂度为O(nlogn),与理论分析相符。

二、快速排序1. 原理快速排序也是一种分治算法。

它选择一个基准元素,将数组中小于等于它的元素放在其左侧,大于它的元素放在其右侧。

然后递归地对左右两个子数组进行同样的操作,直到每个子数组只剩下一个元素。

2. 实现我们实现了两个版本的快速排序:递归版本和非递归版本。

其中,递归版本采用了经典的Lomuto分区方案,而非递归版本则采用了更高效的Hoare分区方案。

3. 性能测试与比较我们同样使用Python内置的time模块对不同规模(10^2 ~ 10^6)的随机整数列表进行了性能测试,并绘制出了运行时间随数组规模增大的变化曲线。

结果表明,快速排序具有很好的平均时间复杂度(O(nlogn)),但最坏情况下时间复杂度会退化到O(n^2)。

三、总结与思考通过本次实验,我们深入理解了分治算法设计策略,并学会了如何实现归并排序和快速排序。

算法设计与分析:递归与分治法-实验报告(总8页)

算法设计与分析:递归与分治法-实验报告(总8页)

算法设计与分析:递归与分治法-实验报告(总8页)实验目的:掌握递归与分治法的基本思想和应用,学会设计和实现递归算法和分治算法,能够分析和评价算法的时间复杂度和空间复杂度。

实验内容:1.递归算法的设计与实现3.算法的时间复杂度和空间复杂度分析实验步骤:1)递归定义:一个函数或过程,在其定义或实现中,直接或间接地调用自身的方法,被成为递归。

递归算法是一种控制结构,它包含了解决问题的基础情境,也包含了递归处理的情境。

2)递归特点:递归算法具有以下特点:①依赖于递归问题的部分解被划分为若干较小的部分。

②问题的规模可以通过递推式递减,最终递归终止。

③当问题的规模足够小时,可以直接求解。

3)递归实现步骤:①确定函数的定义②确定递归终止条件③确定递归调用的过程4)经典实例:斐波那契数列递推式:f(n) = f(n-1) + f(n-2)int fib(int n) {if (n <= 0)return 0;else}5)优化递归算法:避免重复计算例如,上述斐波那契数列的递归算法会重复计算一些中间结果,影响效率。

可以使用动态规划技术,将算法改为非递归形式。

int f1 = 0, f2 = 1;for (int i = 2; i <= n; i++) {f1 = f2;使用循环避免递归,重复计算可以大大减少,提高效率。

1)分治算法的定义:将原问题分解成若干个规模较小且类似的子问题,递归求解子问题,然后合并各子问题得到原问题的解。

2)分治算法流程:②将问题分解成若干个规模较小的子问题。

③递归地解决各子问题。

④将各子问题的解合并成原问题的解。

3)分治算法实例:归并排序归并排序是一种基于分治思想的经典排序算法。

排序流程:②分别对各子数组递归进行归并排序。

③将已经排序好的各子数组合并成最终的排序结果。

实现源代码:void mergeSort(int* arr, int left, int right) {if (left >= right)while (i <= mid && j <= right)temp[k++] = arr[i] < arr[j] ? arr[i++] : arr[j++];temp[k++] = arr[i++];1) 时间复杂度的概念:指完成算法所需的计算次数或操作次数。

算法设计与分析实验报告

算法设计与分析实验报告

实验一找最大和最小元素与归并分类算法实现(用分治法)一、实验目的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. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

石家庄经济学院
《算法设计与分析》实验报告
姓名:
班级:
学号:
指导教师:
完成日期:
一、实验名称
分治法实验
二、实验目的
1. 掌握分治法的基本思想、求解问题的基本步骤;
2. 掌握分支算法的一般模式;
3. 根据问题采取有效的分解和合并的方式,能够分析确定问题的阈值;
4. 掌握分治算法的时间复杂度,并能利用C语言实现算法。

三、实验内容及要求
1. 大整数乘法。

要求:
(1) 求解两个n位的二进制整数的乘法,设n=2k;
(2) 利用分治的思想分析和求解问题;
(3) 利用C语言实现算法,要求结果正确。

2. 矩阵相乘(选做)
(1) 求解两个n阶方阵的乘法,设n=2k;
(2) 可利用基本的分解方法或者STRANSSEN方法求解;
(3) 利用C语言实现算法,要求结果正确。

四、问题分析及算法设计
1. 大整数乘法
问题分析:
算法设计:
算法复杂度分析:
2. 矩阵乘法
问题分析:
算法设计:
算法复杂度分析:
五、代码及运行结果
六、实验总结
(要求总结本次实验遇到的问题及解决方法,收获和不足,300字以上,提交报告时删去此行)
教师评语:
成绩:优良中及格不及格。

相关文档
最新文档