【报告】分治法实验报告
分治算法实验报告(C语言)
实验1、《分治算法实验》一、实验目的1. 了解分治策略算法思想2. 掌握快速排序、归并排序算法3. 了解其他分治问题典型算法二、实验内容1.编写一个简单的程序,实现归并排序。
2. 编写一段程序,实现快速排序。
3. 编写程序实现循环赛日程表。
设有n=2k个运动员要进行网球循环赛。
现要设计一个满足以下要求的比赛日程表:(1)每个选手必须与其它n-1个选手各赛一次(2)每个选手一天只能赛一场(3)循环赛进行n-1天三、算法思想分析1.归并排序先是将待排序集合分成两个大小大致相同的集合,分别对每个集合进行排序,递归调用归并排序函数,再是调用合并函数,将两个集合归并为一个排好序的集合。
2.快速排序先是选择关键数据作为比较量,然后将数组中比它小的数都放到它的左边,比它大的数放大右边,再对左右区间重复上一步,直至各个区间只有一个数。
3.循环赛日程表先将选手分为两部分,分别排序,再将两部分合并,合并时由于循环赛的规律得知直接将左上角的排序表复制到右下角,左下角的排序表复制到右上角即可。
分成两部分时需要利用递归不断分下去直至只剩下一位选手。
四、实验过程分析1.通过归并算法我对分治算法有了初步的实际操作经验,快速排序与归并算法有很大的相似点,但是在合并时的方法不一样,而循环赛日程表则是思路问题,这个题目编程难点应该在于合并时数组调用的for循环的次数以及起始位置问题。
2.对于分治算法一般是将大规模问题分解为小问题,通过递归不断分下去,然后对每个小规模用一个函数去求解。
适用于小规模独立且易解,可以合并到大问题具有最优子结构的问题。
3.归并排序和快速排序熟悉书本及PPT基本没有问题,循环赛日程表则是纠结了很久,一开始算法思路并不是十分清晰所以错了很多次,后来想了很久再观察PPT的循环赛日程表得知最终算法,编写代码中遇到了一个小问题,有一部分选手未排序,如图所示:图中有部分选手未排序,即左下角排序出现了问题,后来直接静态调试,自己按照代码用实际数据去试了一遍,发现是排序时的for循环的次数不对。
分治算法实验
分治算法实验(用分治法查找数组元素的最大值和最小值)算法分析与设计实验报告第一次实验实验步骤关键代码}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); }。
分治算法实验报告.doc
一、实验目的1.加深对分治算法的基本思想、基本步骤和一般形式的理解,掌握分治算法设计的基本方法。
2.用分治法设计L型组件填图问题的算法,分析其复杂性,并实现;3.用分治法设计求数列中的第1~k小元素的算法,分析其复杂性,并实现。
二、实验内容(一)L型组件填图问题1.问题描述设B是一个n×n棋盘,n=2k,(k=1,2,3,…)。
用分治法设计一个算法,使得:用若干个L型条块可以覆盖住B的除一个特殊方格外的所有方格。
其中,一个L型条块可以覆盖3个方格。
且任意两个L型条块不能重叠覆盖棋盘。
例如:如果n=2,则存在4个方格,其中,除一个方格外,其余3个方格可被一L型条块覆盖;当n=4时,则存在16个方格,其中,除一个方格外,其余15个方格被5个L型条块覆盖。
2. 具体要求输入一个正整数n,表示棋盘的大小是n*n的。
输出一个被L型条块覆盖的n*n棋盘。
该棋盘除一个方格外,其余各方格都被L型条块覆盖住。
为区别出各个方格是被哪个L型条块所覆盖,每个L型条块用不同的数字或颜色、标记表示。
3. 测试数据(仅作为参考)输入:8输出:A 2 3 3 7 7 8 82 2 13 7 6 6 84 1 15 9 96 104 45 5 0 9 10 1012 12 13 0 0 17 18 1812 11 13 13 17 17 16 1814 11 11 15 19 16 16 2014 14 15 15 19 19 20 204. 设计与实现的提示对2k×2k的棋盘可以划分成若干块,每块棋盘是原棋盘的子棋盘或者可以转化成原棋盘的子棋盘。
注意:特殊方格的位置是任意的。
而且,L型条块是可以旋转放置的。
为了区分出棋盘上的方格被不同的L型条块所覆盖,每个L型条块可以用不同的数字、颜色等来标记区分。
5. 扩展内容可以采用可视化界面来表示各L型条块,显示其覆盖棋盘的情况。
(二) 求第k小项三、程序清单及实验过程和结果分析(一)#include "stdafx.h"#include "stdio.h"#define M 1024int table[M][M];int index;void LFill( int startx , int starty , int width , int x , int y ){int half=width/2;if( width==2 ){//填充if( table[startx][starty]==0 ) table[startx][starty]=index;if( table[startx+1][starty]==0 ) table[startx+1][starty]=index;if( table[startx][starty+1]==0 ) table[startx][starty+1]=index;if( table[startx+1][starty+1]==0 ) table[startx+1][starty+1]=index;index++;}else{//判断x,y方块位置//根据该位置用L填充if( x < startx+half ){if( y < starty+half ) //左上{table[startx+half-1][starty+half]=index; //左下table[startx+half][starty+half-1]=index; //右上table[startx+half][starty+half]=index; //右下index++;LFill(startx,starty,half,x,y);LFill(startx,starty+half,half,startx+half-1,starty+half);//左下LFill(startx+half,starty,half,startx+half,starty+half-1);//右上LFill(startx+half,starty+half,half,startx+half,starty+half);//右下}else{//左下table[startx+half-1][starty+half-1]=index; //左上table[startx+half][starty+half-1]=index; //右上table[startx+half][starty+half]=index; //右下index++;LFill(startx,starty,half,startx+half-1,starty+half-1);//左上LFill(startx,starty+half,half,x,y);LFill(startx+half,starty,half,startx+half,starty+half-1);//右上LFill(startx+half,starty+half,half,startx+half,starty+half);//右下}}else{if( y<starty+half )//右上{table[startx+half-1][starty+half]=index;table[startx+half-1][starty+half-1]=index;table[startx+half][starty+half]=index;index++;LFill(startx,starty,half,startx+half-1,starty+half-1);//左上LFill(startx,starty+half,half,startx+half-1,starty+half);//左下LFill(startx+half,starty,half,x,y);LFill(startx+half,starty+half,half,startx+half,starty+half);//右下}else{//右下table[startx+half][starty+half-1]=index;table[startx+half-1][starty+half-1]=index;table[startx+half-1][starty+half]=index;index++;LFill(startx,starty,half,startx+half-1,starty+half-1);//左上LFill(startx,starty+half,half,startx+half-1,starty+half);//左下LFill(startx+half,starty,half,startx+half,starty+half-1);//右上LFill(startx+half,starty+half,half,x,y);}}}}int main(){index=1;int n,i,j,p,q;printf("输入n的大小(n=2^k):");scanf("%d",&n);for(i=0;i<n;i++)for(j=0;j<n;j++)table[i][j]=0;printf("输入特殊位置坐标:");scanf("%d%d",&p,&q);table[p][q]=-1;LFill(0,0,n,p,q);for(i=0;i<n;i++){for(j=0;j<n;j++){if(i==p&&j==q) printf(" A");elseprintf("%5d",table[i][j]);}printf("\n");}}(二)#include "stdafx.h"#include "stdio.h"#define M 100void sort(int a[],int n){int i,j,t;for(i=1;i<=n;i++)for(j=i+1;j<=n;j++)if(a[i]>a[j]){t=a[i];a[i]=a[j];a[j]=t;}}int select(int a[],int low,int high,int k){int pp=low+high-1;if(pp<44){sort(a,high);return a[k];}int b[50],c[50];int i=1,j=1,t=1;for(i=1;i<=high;i++)//对每组排序后分别取中项存于数组c中,再对数组c排序{b[j++]=a[i];if( i % (high/5) ==0 || i==high){sort(b,j-1);c[t++]=b[j/2];j=1;}}int mid=t/2;sort(c,t-1);int aa[50],bb[50],cc[50];int p=1,q=1,r=1;for(i=1;i<=high;i++){if(a[i]>c[mid]) cc[r++]=a[i];else if(a[i]<c[mid]) aa[p++]=a[i];else if(a[i]==c[mid]) bb[q++]=a[i];}p--;q--;r--;if(p>=k) return select(aa,1,p,k);else if( (p+q) >=k) return c[mid];else return select(cc,1,r,k-p-q);}int main(){int n,a[100],i,k;scanf("%d",&n);for(i=1;i<=n;i++)scanf("%d",&a[i]);scanf("%d",&k);printf("第%d小项为:%d\n",k,select(a,1,n,k) );return 0;}。
分治策略算法实验报告
分治策略算法实验报告引言分治策略是一种经典的算法设计策略,也是算法设计中最重要的思想之一。
其基本思想是将大问题划分成小的、相互独立的子问题,再将子问题合并求解,最终得到原问题的解。
本实验将通过实际例子,验证分治策略算法的有效性。
实验内容本实验选择两个经典的算法问题进行实现和验证,分别是二分查找和快速排序。
这两个问题在算法领域都有重要的应用价值,也是实践分治算法的好例子。
问题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)实验结果为了验证分治策略算法的有效性,我们分别对上述两个问题进行了测试。
分治法实验总结
分治法实验总结
分治法是一种常用的算法设计策略,它将问题分解成若干个子问题,然后递归地解决这些子问题,最后将子问题的解合并成原问题的解。
在本次实验中,我们通过实现归并排序和快速排序两个算法,深入理解了分治法的思想和实现方式。
我们实现了归并排序算法。
归并排序的基本思想是将待排序的序列分成若干个子序列,每个子序列都是有序的,然后再将子序列合并成一个有序的序列。
在实现过程中,我们采用了递归的方式,将序列不断地分成两半,直到每个子序列只有一个元素,然后再将这些子序列两两合并,直到最终得到一个有序的序列。
归并排序的时间复杂度为O(nlogn),是一种稳定的排序算法。
接着,我们实现了快速排序算法。
快速排序的基本思想是选择一个基准元素,将序列分成两个部分,一部分比基准元素小,一部分比基准元素大,然后递归地对这两个部分进行排序。
在实现过程中,我们选择了序列的第一个元素作为基准元素,然后使用两个指针分别从序列的两端开始扫描,将比基准元素小的元素放在左边,将比基准元素大的元素放在右边,最后将基准元素放在中间,然后递归地对左右两个部分进行排序。
快速排序的时间复杂度为O(nlogn),但是在最坏情况下,时间复杂度会退化为O(n^2)。
通过实现归并排序和快速排序两个算法,我们深入理解了分治法的
思想和实现方式。
分治法是一种非常重要的算法设计策略,可以用来解决很多复杂的问题,比如最近点对问题、矩阵乘法问题等。
在实际应用中,我们可以根据具体问题的特点选择合适的分治算法,以提高算法的效率和准确性。
分治发实验报告
分治法学习心得一:分治法原理:分治发既是将一个问题分解成数个相同的类型的问题进行解答,他要求每个子问题之间相互独立,类型与原问题是相似的,对于每个子问题是能够直接求解的,所有子问题的解最终之和就是原问题的解。
在分治发的学习中,进行问题的分解是至关重要的一步,首当其冲的就是问题合理的分解,能够将原问题分解成容易求解的子问题是分治发的核心。
二:就分治发分解的心得体会:分治发包含众多的排序算法如:合并排序、二分搜索(也可看做是排序的过程)、快速排序等。
其中的原理都是分治发。
以二分搜索为例来看,我们知道二分法是将一个有序的元素组合进行二分操作,然后在对于分开的前后部分进行二分,重复调用二分算法直到找到需要的元素。
这个过程既是将一个大的问题转换成了两个与原问题同类型的小问题从而解决。
那么对于分治发而言是否只要找到了对应的子问题就能够解决相应的问题?理论上是肯定的,只要满足分治发的条件必将能够写出一个循环调用的函数解决问题。
那么对于一个分治发如何找到对应的子问题以及如何找到最好的子问题能偶方便的解决问题,我觉得是分治发中至关重要的。
下面作为我学习过程中对于找到相应最优的子问题过程的体会:1)找到问题的分解子问题:这是最基础的一步,如果找不到对应合理的子问题,就谈不上最优子问题。
2)对于子问题算法进行时间复杂度与空间复杂度的评估。
例如快速排序来说,在最坏的情况下回出现n2的时间。
那么如何改进此算法?课本中提到用设置主元的方法解决问题,既选取随机整数,以选取的数为主元进行计算排序,从而大大避免了最坏情况的出现概率。
从而使快速排序更加完善,同时,我们知道,对于很多时候,快速排序并不一定是快速的。
尽管对于任意长度的元素我们都可以使用快速排序将其进行划分,但是当数据长度很小的时候,我们完全可以直接进行元素的直接搜索,因为此时进行排序的时间上与快速排序相差无几,甚至比快速排序还要快(第一个元素主元时)。
从而进行分治发解决问题时,我们需要对一个子问题进行解析,是否其时间复杂度上能够让问题变得简单,最坏的情况又是什么。
分治法实验报告
算法实验报告一分治法实验一、实验目的及要求利用分治方法设计大整数乘法的递归算法,掌握分治法的基本思想和算法设计的基本步骤。
要求:设计十进制的大整数乘法,必须利用分治的思想编写算法,利用c语言(或者c++语言)实现算法,给出程序的正确运行结果。
(必须完成)设计二进制的大整数乘法,要求利用分治的思想编写递归算法,并可以实现多位数的乘法(利用数组实现),给出程序的正确运行结果。
(任选)二、算法描述1、输入两个相同位数的大整数u,v 输出uv的值判断大整数的位数i;w=u/10^(i/2);y=v/10^(i/2);x=u-w*10^(i/2);z= v-y*10^(i/2);然后将w,x,y,z代入公式求得最后结果uv=wy10^i+((w+x)(y+z)-wy-xz)10^(i/2)+xz三、调试过程及运行结果在实验中我遇到的问题:原来以为这两个大整数的位数不同,结果题目要求是相同位数的大整数在写10的多少次方时,写的是10^(i/2),10^(i),结果不对,我就将它改成了for循环语句四、实验总结在本次实验中,我知道了分治算法,以及分治算法的基本思想。
我还掌握了编写大整数乘法的算法与步骤,以及如何修改在编写程序时遇到的问题。
五、附录(源程序代码清单)1、#include<iostream.h> int weishu(int x){int i;while(x!=0){ x=x/10;i++;}return i;}void main(){int u,v;cout<<输入两个位数相同的大整数:<<endl; cin>>u;cin>>v;int i,j,m,n;int p,x,y,z,w;int a=1;int b=1;i=weishu(u);for(int k=1;k<=i;k++){a=a*10;}for(int q=1;q<=i/2;q++) {b=b*10;}w=u/b;y=v/b;x=u-w*b;z=v-y*b;p=w*y*a+((w+x)*(y+z)-w*y-x*z)*b+x*z; cout<<u<<*<<v<<=<<p; }教师评语:成绩:√优良中及格不及格算法实验报告二动态规划法实验一、实验目的及要求利用动态规划方法设计背包问题算法,掌握动态规划法的基本思想和算法设计的基本步骤。
分治法实验报告
分治法实验报告分治法实验报告一、引言分治法是一种重要的算法设计策略,它将一个大问题分解成若干个小问题,并通过递归的方式解决这些小问题,最终将它们的解合并起来得到原问题的解。
本实验旨在通过实际案例,探索分治法的应用和效果。
二、背景在计算机科学领域,分治法常常被用于解决一些复杂的问题,如排序、搜索、图算法等。
它的核心思想是将问题划分为更小的子问题,然后分别解决这些子问题,最后将它们的解合并起来得到原问题的解。
通过这种方式,我们可以降低问题的复杂度,提高算法的效率。
三、实验目的本实验旨在通过实际案例,验证分治法在问题解决中的有效性,并探索其在不同问题上的应用效果。
通过对比不同算法的运行时间和结果准确性,评估分治法在不同场景下的适用性。
四、实验过程本次实验选取了两个典型的问题,分别是最大子数组和快速排序。
首先,我们使用分治法来解决最大子数组问题。
该问题要求在一个给定的数组中,找到一个连续子数组,使得该子数组的和最大。
我们将数组分为两半,分别求解左半部分和右半部分的最大子数组,然后再考虑跨越中点的最大子数组。
通过递归的方式,最终得到整个数组的最大子数组。
接着,我们使用分治法来实现快速排序算法。
快速排序是一种高效的排序算法,它的核心思想是通过选择一个基准元素,将数组分为两个部分,使得左边的元素都小于等于基准元素,右边的元素都大于等于基准元素。
然后,对左右两个部分分别递归地进行快速排序,最终得到有序的数组。
五、实验结果通过对最大子数组和快速排序问题的实验,我们得到了以下结果。
首先,分治法在解决最大子数组问题上表现出色。
通过将问题划分为更小的子问题,我们可以在较短的时间内找到最大子数组,大大提高了算法的效率。
其次,在快速排序问题上,分治法同样展现了强大的能力。
通过不断地划分数组并进行排序,我们可以快速得到有序的结果。
六、实验分析分治法作为一种重要的算法设计策略,具有许多优点。
首先,它可以将复杂的问题分解为简单的子问题,降低了问题的复杂度,提高了算法的效率。
分治法实验总结
分治法实验总结
分治法是一种重要的算法思想,它的核心思想就是将单个问题划
分为多个相似的子问题,并通过递归思想将这些子问题分别解决,最
终合并起来得到整个问题的解。
在算法设计中,应用分治法能够提高
算法的效率,减少时间复杂度,实现更加高效的计算。
在实验中,我们通过使用分治法,解决了两个典型的问题:二分
查找和归并排序。
在二分查找中,我们将数组一分为二,通过递归思
想分别查找数组左半部分和右半部分,最终得到目标元素在数组中的
位置。
在归并排序中,我们同样将数组一分为二,分别对两个子数组
进行排序,然后通过归并操作将排序好的子数组合并为一个有序数组。
通过实验我们发现,使用分治法可以大大提高算法效率,减少时
间复杂度。
在二分查找算法中,平均时间复杂度为O(log n),比传统
的线性查找算法时间复杂度要低得多。
在归并排序中,时间复杂度为
O(nlogn),比传统的冒泡排序、插入排序更加高效。
总的来说,分治法是一种高效、可拓展的算法思想,能够为我们
解决一些复杂的算法问题提供帮助。
在具体的应用过程中,我们还需
要加强对算法的理解和分析能力,结合具体问题进行灵活的算法设计
和选择,以达到更好的效果。
分治法实验报告详细
分治法实验报告详细引言分治法是一种高效的问题解决方法,这种方法把一个复杂的问题划分成若干个规模较小的子问题,然后逐个解决这些子问题,并将子问题的解组合起来,形成原问题的解。
在本实验中,我们将通过实际案例来演示和验证分治法的有效性和高效性。
实验目的本实验的主要目的是探讨分治法在解决实际问题中的应用,验证其在问题规模较大时的效果,并通过与其他算法的对比分析,评估分治法的优势和不足。
实验材料与方法我们选择了一个具体的实际问题作为案例:在一个包含n个元素的列表中,查找特定元素x的位置。
为了模拟问题的规模,我们首先生成了一个包含1000个随机整数的列表,然后从中随机选择一个元素作为我们要查找的目标x。
我们采用了如下的分治法解决方案:1. 将列表分成两个子列表,分别包含前半部分和后半部分的元素。
2. 如果目标元素x等于列表的中间元素,则返回中间元素的位置。
3. 如果目标元素x小于列表的中间元素,则递归调用步骤1,查找前半部分子列表中的目标元素x。
4. 如果目标元素x大于列表的中间元素,则递归调用步骤1,查找后半部分子列表中的目标元素x。
5. 如果子列表为空,则说明目标元素x不存在于列表中。
实验结果与分析我们依次使用二分查找法和分治法来解决上述问题,并记录它们的运行时间。
重复实验10次,并计算它们的平均运行时间。
实验结果如下:- 二分查找法平均运行时间:0.002秒- 分治法平均运行时间:0.001秒通过实验数据可以看出,分治法的运行时间明显优于二分查找法。
这是因为分治法通过将问题划分为更小的子问题,使得每个子问题的规模减小,从而减少了解决每个子问题的时间。
而二分查找法则只是将问题逐步缩小,没有有效地利用子问题之间的联系。
结论通过本实验,我们验证了分治法在解决实际问题中的有效性和高效性。
与其他算法相比,分治法在处理问题规模较大时表现出更好的性能。
因此,我们可以得出结论,对于复杂问题的解决,分治法是一种值得采用的优秀方法。
分治法实验报告范文
分治法实验报告范文分治法(Divide and Conquer)是一种计算机算法设计方法,它通过将问题分解成更小的子问题,然后逐个解决这些子问题,最后将结果合并起来得到最终解。
本实验旨在通过实际问题应用分治法,探究其效果和应用场景。
一、实验目的和原理实验目的:了解分治法的基本原理和实现方式,比较分治法与其他算法的效率和适用性实验原理:分治法将一个问题划分成更小的子问题,递归地解决这些子问题,然后将结果合并起来得到最终解。
二、实验步骤和结果1.实验步骤:(1)选择合适的实际问题,将其转化为具体的算法问题。
(2)实现分治法算法,并编写程序。
(3)测试算法的效果,比较其与其他算法的性能和效率。
2.实验结果:以寻找数组中最大数为例,来展示分治法的应用。
```#include <iostream>using namespace std;//定义找最大数的函数int findMax(int arr[], int left, int right)if (left == right)return arr[left];} elseint mid = (left + right) / 2;int maxLeft = findMax(arr, left, mid);int maxRight = findMax(arr, mid + 1, right);if (maxLeft > maxRight)return maxLeft;} elsereturn maxRight;}}int maiint arr[] = {15, 18, 29, 43, 2, 5, 11};int n = sizeof(arr) / sizeof(arr[0]);int maxNum = findMax(arr, 0, n - 1);cout << "The maximum number is: " << maxNum << endl;return 0;```实验结果如下:The maximum number is: 43三、实验讨论和总结1. 实验讨论:通过实验可以看出,分治法能够较快地找到数组中的最大数,时间复杂度为O(logn),效率较高。
分治算法实验(用分治法实现归并排序算法)
实 验 比 较 实 验 得 分
附录: 完整代码(分治法)
#include<iostream> #include<time.h> #include<iomanip> using namespace std; void merge(int A[],int B[],int low,int mid,int high)
{ if(left<right) //如果序列中元素超过一个才会进行划分 { int mid=(left+right)/2; //将序列从中位数地方划分为两 个子序列 mergesort(a,b,left,mid); // 对左半边子序列递归调用自身,将子序列变成有序 mergesort(a,b,mid+1,right); //对右边子序列递归调用自 身,将子序列变成有序 merge(a,b,left,mid,right); //调用合并函数,将子序列 合并,实现整个数列的有序 for(int h=left;h<=right;h++) //将临时有序的数组复制 回原数组¦ { a[h]=b[h]; } } } void ran(int *input,int n) //数组随机生成函数 { int i; srand(time(0)); for(i=0;i<n;i++) input[i]=rand(); input[i]='\0'; } int a[1000000]; int b[1000000]; int main() { int n; cout<<"请输入要归并排序的记录个数:"<<endl; for(int j=0;j<5;j++) { cin>>n; ran(a,n); //生成数组
2018-分治法实验报告-实用word文档 (10页)
本文部分内容来自网络整理,本司不为其真实性负责,如有异议或侵权请及时联系,本司将立即删除!== 本文为word格式,下载后可方便编辑和修改! ==分治法实验报告篇一:算法实验报告一分治法实验算法实验报告一分治法实验一、实验目的及要求利用分治方法设计大整数乘法的递归算法,掌握分治法的基本思想和算法设计的基本步骤。
要求:设计十进制的大整数乘法,必须利用分治的思想编写算法,利用c语言(或者c++语言)实现算法,给出程序的正确运行结果。
(必须完成)设计二进制的大整数乘法,要求利用分治的思想编写递归算法,并可以实现多位数的乘法(利用数组实现),给出程序的正确运行结果。
(任选)二、算法描述1、输入两个相同位数的大整数u,v输出uv的值判断大整数的位数i;w=u/10^(i/2);y=v/10^(i/2);x=u-w*10^(i/2);z= v-y*10^(i/2);然后将w,x,y,z代入公式求得最后结果uv=wy10^i+((w+x)(y+z)-wy-xz)10^(i/2)+xz三、调试过程及运行结果在实验中我遇到的问题:原来以为这两个大整数的位数不同,结果题目要求是相同位数的大整数在写10的多少次方时,写的是10^(i/2),10^(i),结果不对,我就将它改成了for 循环语句四、实验总结在本次实验中,我知道了分治算法,以及分治算法的基本思想。
我还掌握了编写大整数乘法的算法与步骤,以及如何修改在编写程序时遇到的问题。
五、附录(源程序代码清单)1、#include<iostream.h>int weishu(int x){int i;while(x!=0){x=x/10;i++;}return i;}void main(){int u,v;cout<<"输入两个位数相同的大整数:"<<endl;cin>>u;cin>>v;int i,j,m,n;int p,x,y,z,w;int a=1;int b=1;i=weishu(u);for(int k=1;k<=i;k++){a=a*10;}for(int q=1;q<=i/2;q++){b=b*10;}w=u/b;y=v/b;x=u-w*b;z=v-y*b;p=w*y*a+((w+x)*(y+z)-w*y-x*z)*b+x*z; cout<<u<<"*"<<v<<"="<<p;}教师评语:成绩:√优良中及格不及格算法实验报告二动态规划法实验。
分治法金块实验报告
分治法金块实验报告引言分治法是一种高效的问题解决方法,通过将问题划分为多个子问题并递归地解决,然后将子问题的解合并得到原始问题的解。
本次实验使用了分治法解决了金块分割问题。
金块分割问题是将一块金块分割成多个相等大小的小块的问题。
实验目的本次实验旨在通过实践掌握分治法的应用,了解其原理和算法实现,进一步加深对分治法的理解。
实验步骤1. 首先,将一块金块均匀分割成4块。
2. 然后,从4块金块中找到最重的一块。
3. 接着,将最重的金块与其他3块再次均匀分割成4块。
4. 重复上述过程,直到金块的数量足够小无法再分割。
5. 最后,计算并输出得到的最重金块的重量。
实验结果通过实验,我们得到了一块金块分割的过程及最终的结果。
实验中,我们使用了递归的方法来实现分治法。
以下是分治法金块分割的过程演示:1. 原始金块:10 kg2. 第一次分割:10 kg -> 2.5 kg + 2.5 kg + 2.5 kg + 2.5 kg3. 第二次分割:2.5 kg -> 0.625 kg + 0.625 kg + 0.625 kg + 0.625 kg4. 第三次分割:0.625 kg -> 0.15625 kg + 0.15625 kg + 0.15625 kg +0.15625 kg5. 第四次分割:0.15625 kg -> 0.03906 kg + 0.03906 kg + 0.03906 kg + 0.03906 kg6. 第五次分割:0.03906 kg -> 0.00977 kg + 0.00977 kg + 0.00977 kg + 0.00977 kg7. 第六次分割:0.00977 kg -> 0.00244 kg + 0.00244 kg + 0.00244 kg + 0.00244 kg8. 第七次分割:0.00244 kg -> 0.00061 kg + 0.00061 kg + 0.00061 kg + 0.00061 kg9. 第八次分割:0.00061 kg -> 0.00015 kg + 0.00015 kg + 0.00015 kg + 0.00015 kg经过八次分割,最终得到的金块重量是0.00015 kg。
《算法设计与分析》课程实验报告 (分治法(三))
《算法设计与分析》课程实验报告实验序号: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∣度量。
分冶法快速排序实验报告
一、实验目的1. 理解分治法的基本思想及其在排序算法中的应用。
2. 掌握快速排序算法的原理和实现过程。
3. 分析快速排序算法的性能特点,包括时间复杂度和空间复杂度。
4. 通过实验验证快速排序算法在实际数据排序中的效率。
二、实验内容1. 快速排序算法原理介绍2. 快速排序算法的代码实现3. 快速排序算法的性能分析4. 实验数据准备与结果分析三、实验原理快速排序是一种基于分治法的排序算法。
其基本思想是将待排序的序列分为两个子序列,其中一个子序列的元素都小于另一个子序列的元素,然后递归地对这两个子序列进行快速排序。
快速排序的关键在于选择一个合适的基准元素,并通过交换元素的位置使得基准元素左边的元素都不大于它,右边的元素都不小于它。
四、实验步骤1. 快速排序算法原理介绍快速排序算法的主要步骤如下:- 选择一个基准元素(pivot),通常选择序列的第一个或最后一个元素。
- 将序列分为两个子序列,一个子序列包含所有小于基准元素的元素,另一个子序列包含所有大于基准元素的元素。
- 递归地对这两个子序列进行快速排序。
2. 快速排序算法的代码实现下面是快速排序算法的Python代码实现:```pythondef quick_sort(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 quick_sort(left) + middle + quick_sort(right)# 测试代码arr = [3, 6, 8, 10, 1, 2, 1]sorted_arr = quick_sort(arr)print(sorted_arr)```3. 快速排序算法的性能分析快速排序算法的平均时间复杂度为O(nlogn),最坏情况下的时间复杂度为O(n^2)。
-实验1分治法
-实验1分治法⼀、实验⽬的1.理解分治法的⽅法;2. 掌握使⽤分治法解决⼀般问题的步骤;3. 掌握分治算法求解数组的最⼤值和最⼩值的⽅法。
⼆、实验原理在⼀个给定数组中查找最⼤值和最⼩值是⼀类常见的问题,也是解决其他⼀些算法的基础。
假设给定数组为a,数组中含有n个元素,⼀般的算法是在数组中进⾏直接循环的次数在算法第2⾏给出,为(n-2)+1=n-1次,因此,算法元素⽐较总次数为2(n-1)次。
现在采⽤分治的思想,假设数组的长度为2的整数幂,将数组分割成两半,分别为a[0…(n/2)-1]和a[n/2…n-1],在每⼀半中分别查找最⼤值和最⼩值,并返回这两个最⼩值中的最⼩值以及两个最⼤值中的最⼤值。
假设给定数组为a,数组的下标上界和下界分别为low和high,则其算法伪接⽐较数组的两个元素,选出最⼤值和最⼩值,此为函数的递归终⽌条件;代码第7⾏和第8⾏是两个递归调⽤,分别在数组的下标范围[low,mid]和[mid+1,high]查找最⼩值和最⼤值,第9⾏⽐较两个最⼤值取其中较⼤者,第10⾏⽐较两个最⼩值取较⼤者。
代码的第2、9和10⾏涉及到元素的⽐较,第7、8⾏由于递归也产⽣元素⽐较,因此令算法总的元素⽐较次数为C(n),则有>+==22)2/(221)(n n C n n C 若若对递推式进⾏求解22/3 22)2/( 2)2(2 22...22)2/(2 ...248)8/(824)2)8/(2(4 24)4/(42)2)4/(2(22)2/(2)(11122111-=-+=+=+++++==+++=+++=++=++=+=∑-=-----n n C n C n C n C n C n C n C n C k k j jk k k k k 得到minmax 算法的元素⽐较总次数为3n/2-2,优于直接⽐较的性能。
三、实验内容及要求1. 编写程序使⽤分治算法MINMAX 求解数组的最⼩值和最⼤值,并⽤实际数组对算法进⾏测试。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
石家庄经济学院
《算法设计与分析》实验报告
姓名:
班级:
学号:
指导教师:
完成日期:
一、实验名称
分治法实验
2、实验目的
1.掌握分治法的基本思想、求解问题的基本步骤;
2.掌握分支算法的一般模式;
3.根据问题采取有效的分解和合并的方式,能够分析确定问题的阈值;
4.掌握分治算法的时间复杂度,并能利用C语言实现算法。
四、问题分析及算法设计
1.大整数乘法
问题分析:
算法设计:
算法复杂度分析:
2.矩阵乘法
问题分析:
算法设计:
算法复杂度分析:
五、代码及运行结果
六、实验总结
(要求总结本次实验遇到的问题及解决方法,收获和不足,300字以上,提交报告时删去此行)
教师评语:
成绩:优良中及格不及格
此文档是由网络收集并进行重新排版整理.word可编辑版本!
三、实验内容及要求
1.大整数乘法。
要求:
(1)求解两个n位的二进制整数的乘法,设n=2k;
(2)利用分治的思想分析和求解问题;
(3)利用C语言实现算法,要求结果正确。
2.矩阵相乘(选做)
(1)求解两个n阶方阵的乘法,设n=2k;
(2)可利用基本的分解方法或者STRANSSEN方法求解;
(3)利用C语言实现算法,要求结果正确。