分治算法实验报告
分治算法实验报告(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)实验结果为了验证分治策略算法的有效性,我们分别对上述两个问题进行了测试。
分治算法实验(用分治法实现快速排序算法)
算法分析与设计实验报告第四次附加实验while(a[--j]>x);if(i>=j){break;}Swap(a[i],a[j]);}a[p] = a[j]; //将基准元素放在合适的位置a[j] = x;return j;}//通过RandomizedPartition函数来产生随机的划分template<class Type>int RandomizedPartition(Type a[],int p,int r){int i = Random(p,r);Swap(a[i],a[p]);return Partition(a,p,r);}较小个数排序序列的结果:测试结果较大个数排序序列的结果:附录:完整代码(分治法)// 随机后标记元素后的快速排序#include <iostream>#include <ctime>#include <time.h>#include <iomanip>using namespace std;int a[1000000]; //定义全局变量用来存放要查找的数组template <class Type>void Swap(Type &x,Type &y); //声明swap 函数inline int Random(int x, int y); //声明内联函数template <class Type>int Partition(Type a[],int p,int r); //声明Partition 函数更大个数排序序列的结果:实验心得快速排序在之前的数据结构中也是学过的,在几大排序算法中,快速排序和归并排序尤其是重中之重,之前的快速排序都是给定确定的轴值,所以存在一些极端的情况使得时间复杂度很高,排序的效果并不是很好,现在学习的一种利用随机化的快速排序算法,通过随机的确定轴值,从而可以期望划分是较对称的,减少了出现极端情况的次数,使得排序的效率挺高了很多,与后面的随机化算法想呼应,而且关键的是对于随机生成函数,通过这一次的实验和自己的学习终于弄明白是怎么回事了,不错。
分冶法快速排序实验报告
一、实验目的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)。
分治法实验报告
算法实验报告一分治法实验一、实验目的及要求利用分治方法设计大整数乘法的递归算法,掌握分治法的基本思想和算法设计的基本步骤。
要求:设计十进制的大整数乘法,必须利用分治的思想编写算法,利用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 分治算法
《算法设计与分析》实验报告实验1 分治算法姓名学号班级实验日期2015.1.13 实验地点一、实验目的1、掌握分治算法的设计思想与分析方法;2、掌握归并排序、快速排序等高效排序算法。
二、实验环境1、硬件环境CPU:酷睿i5内存:4GB硬盘:1TB2、软件环境操作系统:win10编程环境:Dev-C++编程语言:C语言三、实验内容1、编写程序,实现归并排序算法。
(1)归并排序算法归并排序是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,再使子序列段间有序。
(2)归并排序算法分析时间复杂度:O(nlogn)空间复杂度O(nlogn)(3)编程要求●待排序数组长度至少为16,数组中可以有相同元素;●按递增排序。
(4)程序代码(含注释)//归并排序算法实现#include <stdio.h>#include <malloc.h>#define MAXE 50 //线性表中最多元素个数typedef int KeyType;typedef char InfoType[10];typedef struct //记录类型{KeyType key; //关键字项InfoType data; //其他数据项,类型为InfoType} RecType;void Merge(RecType R[],int low,int mid,int high)//将两个有序表R[low..mid]和R[mid+1..high]归并为一个有序表R[low..high]中{RecType *R1;int i=low,j=mid+1,k=0; //k是R1的下标,i、j分别为第1、2段的下标R1=(RecType *)malloc((high-low+1)*sizeof(RecType)); //动态分配空间while (i<=mid && j<=high) //在第1段和第2段均未扫描完时循环if (R[i].key<=R[j].key) //将第1段中的记录放入R1中{R1[k]=R[i];i++;k++;}else //将第2段中的记录放入R1中{R1[k]=R[j];j++;k++;}while (i<=mid) //将第1段余下部分复制到R1{R1[k]=R[i];i++;k++;}while (j<=high) //将第2段余下部分复制到R1{R1[k]=R[j];j++;k++;}for (k=0,i=low;i<=high;k++,i++) //将R1复制回R中R[i]=R1[k];}void MergePass(RecType R[],int length,int n) //实现一趟归并{int i;for (i=0;i+2*length-1<n;i=i+2*length) //归并length长的两相邻子表Merge(R,i,i+length-1,i+2*length-1);if (i+length-1<n) //余下两个子表,后者长度小于lengthMerge(R,i,i+length-1,n-1); //归并这两个子表}void MergeSort(RecType R[],int n) //二路归并排序算法{int length,k,i=1; //i用于累计归并的趟数for (length=1;length<n;length=2*length){MergePass(R,length,n);printf(" 第%d趟归并",i++); //输出每一趟的排序结果for (k=0;k<n;k++)printf("%4d",R[k].key);printf("\n");}}int main(){int i,k,n;RecType R[MAXE];printf("请输入元素个数n:\n");scanf("%d",&n);printf("请输入%d个元素:\n",n);for (i=0;i<n;i++)scanf("%d",&R[i].key);printf("\n");MergeSort(R,n); // 执行排序函数printf("归并排序结果:\n");printf(" ");for (k=0;k<n;k++)printf("%5d",R[k].key);printf("\n\n");return 0;}(5)程序输出2、编写程序,实现快速排序算法。
分治算法-实验报告
<<算法设计与分析>>实验报告之一实验一分治算法一、实验目的1.掌握分治算法的设计思想与方法,2.熟练使用高级编程语言实现分治算法,3.通过对比简单算法以及不同的分治求解思想,体验分治算法。
二、实验内容4.实现基于枚举方法的凸包求解算法5.实现基于Graham-Scan的凸包求解算法6.实现基于分治思想的凸包求解算法7.对比三种凸包求解算法三、实验过程及结果3.1算法主要步骤及代码三种算法同时用到的凸包输出函数:1. 基于枚举的方法的凸包求解算法利用叉积运算,即可知道任意三个点之间的关系如下:设三角形三点A(x1,y1), B(x2,y2), C(x3,y3),已知点P(x,y)若P在三角形内部,则:1) P与C在AB同侧2) P与A在BC同侧3) P与B在CA同侧2基于Graham-Scan的凸包求解算法1) 将点排序2) 准备堆栈:建立堆栈S,栈指针设为t,将0、1、2三个点压入堆栈S;3)对于下一个点i,只要S[t-1]、S[t]、i不做左转,就反复退栈;将i压入堆栈S4)堆栈中的点即为所求凸包;其中判断左转过程,为判断点i是否在S[t-1]、S[t]构成的向量上方。
算法实现关键代码如下:3基于分之思想的凸包求解算法1)对点按照x轴排序2)分治求解3)规模小于3时,开始合并,合并时使用GrahamScan算法。
算法实现关键代码如下:3.2算法运行结果截图3.3算法性能曲线3.4结果分析根据实验结果可以得出,枚举法只能应用在在数据量较小的凸包生成,而随着数据量的增大,时间消耗陡增。
而分治法和graham算法体现了良好的稳定性,在较少的时间内得到结果。
最好的方法还是Graham方法。
四、实验心得通过本次实验,深入理解了分治算法的思想,体会了分治快速处理问题的能力,掌握了分治算法的步骤和基本编程思路。
明确了算法对解决问题的重要性,知道了设计算法比实现算法更重要。
分治法实验报告详细
分治法实验报告详细引言分治法是一种高效的问题解决方法,这种方法把一个复杂的问题划分成若干个规模较小的子问题,然后逐个解决这些子问题,并将子问题的解组合起来,形成原问题的解。
在本实验中,我们将通过实际案例来演示和验证分治法的有效性和高效性。
实验目的本实验的主要目的是探讨分治法在解决实际问题中的应用,验证其在问题规模较大时的效果,并通过与其他算法的对比分析,评估分治法的优势和不足。
实验材料与方法我们选择了一个具体的实际问题作为案例:在一个包含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); //生成数组
算法实验报告-分治法性能分析报告
分治法算法分析作业吴迪2011-3-29本次是第一次算法作业,该部分容包含3个题目的程序代码,分析文档,说明图片等容目录引言 (3)1算法性能比较 (3)1.1问题分析 (3)1.2源程序代码 (3)1.3运行示例 (8)1.4数据分析 (8)(单次录入数据具有较大随机误差,只看增长趋势) (8)2循环赛问题 (9)2.1问题描述 (9)2.2问题分析 (9)2.3 源程序 (10)2.4运行示例 (11)3最大最小值问题 (12)3.1问题描述与分析 (12)3.2源程序 (13)3.3运行示例 (14)引言任何一个可以用计算机求解的问题所需的计算时间都与其规模有关。
问题的规模越小,越容易直接求解,解题所需的计算时间也越少。
分治法是计算机科学中经常使用的一种算法。
设计思想是,将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。
但是不是所有问题都适合用分治法解决。
当求解一个输入规模为n且取值又相当大的问题时,使用蛮力策略效率一般得不到保证。
因此分治策略将问题划分成k个子问题分别求解合并能有效提高计算效率。
1算法性能比较1.1问题分析比较插入排序,合并排序和快速排序性能。
算法性能比较通常是从时间复杂度的角度进行的。
排序算法的复杂度主要和算法中的比较次数和元素交换或移动次数有关。
因而在不同大小规模的问题过统计这两者之和来评判算法的优劣。
同时也可以证明各种算法的时间复杂度与问题规模n之间的关系。
特别说明:本程序中考虑到不同规模的乱序数据输入过程比较复杂,编写了一个规模n的整型数据随机排列函数,能够直接生成指定大小的1-n无序整数列。
1.2源程序代码//2011年3月19日0:20:02//main test.cpp for test#include<iostream>#include<time.h>using namespace std;//全局标记比较次数和移动次数int count_compare=0;int count_move = 0;int count_all(){return count_compare+count_move;}void clear_count(){count_compare=0;count_move = 0;}//insert sortvoid insert_element(int a[],int size,int element) //size before insertion {int i=0;for(i=size-1;i>=0;i--){count_compare++;if(element<a[i]){ a[i+1]=a[i];count_move++;}else break;}a[i+1]=element;count_move++;}void InsertSort(int a[],int size){for(int i=1;i<size;i++){insert_element(a,i,a[i]);}}//merge sortvoid Merge(int c[],int d[], int l, int m, int r){int i = l, j = m+1, k = l;while(i <= m && j <= r){count_compare++;if(c[i] <= c[j]){d[k++]=c[i++];count_move++;}else{ d[k++]=c[j++];count_move++;}}count_compare++;if(i > m){for(int q = j; q <= r; q ++){d[k++] = c[q];count_move++;}}elsefor(int q = i; q <= m; q ++){d[k++] = c[q];count_move++;}}void Copy(int a[],int b[],int l,int r){for(int i=l;i<=r;i++){a[i]=b[i];count_move++;}}void MergeSort(int a[],int left,int right,int size) {if(left < right){count_compare++;int i = (right + left)/2;int p=size; //this is important,mind the value! int *b=new int[p];MergeSort(a, left, i,size);MergeSort(a, i+1, right,size);Merge(a, b, left, i, right);Copy(a,b,left,right);}}//quick sortvoid swap(int a[],int i,int j){int temp=a[i];a[i]=a[j];a[j]=temp;count_move+=3;}int partition(int a[],int p,int r){int i=p,j=r+1;int x=a[p];while(true){while(a[++i]<x&&i<r) count_compare++;while(a[--j]>x) count_compare++;count_compare++;if(i>=j) break;swap(a,i,j);}a[p] =a[j];a[j] = x;count_move++;return j;}void QuickSort(int a[],int p ,int r){if (p < r){int q= partition(a, p , r);QuickSort(a,p,q-1);QuickSort(a,q+1,r);}count_compare++;}//showvoid show_array(int a[],int size) //显示一个数组的所有元素{for(int i=0;i<size;i++){cout << a[i] << " ";}cout << endl;}//random arrayvoid RandomArray(int a[],int size) //随机生成数组含n个元素,其元素各不相同{srand(time(NULL));for(int i=0;i<size;i++) a[i]=0;for(int i=1;i<=size;i++){int p=rand()%size;while(a[p]!=0) {p=(++p)%size;}a[p]=i;}show_array(a,size);}//copy arrayvoid CopyArray(int a[],int b[],int size){for(int i=0;i<size;i++) b[i]=a[i];}int main(){int*a;int *temp_a;int size=4;cin>>size;a=new int [size];temp_a = new int [size];RandomArray(temp_a,size);CopyArray(temp_a,a,size);show_array(a,size);InsertSort(a,size);show_array(a,size);cout << "插入排序比较次数为" << count_compare << endl; cout << "插入排序移动次数为" << count_move << endl; cout << "总规模为" << count_all() << endl;clear_count();CopyArray(temp_a,a,size);show_array(a,size);MergeSort(a,0,size-1,size);show_array(a,size);cout << "合并排序比较次数为" << count_compare << endl; cout << "合并排序移动次数为" << count_move << endl; cout << "总规模为" << count_all() << endl;clear_count();CopyArray(temp_a,a,size);show_array(a,size);QuickSort(a,0,size-1);show_array(a,size);cout << "快速排序比较次数为" << count_compare << endl; cout << "快速排序移动次数为" << count_move << endl; cout << "总规模为" << count_all() << endl;show_array(a,size);system("pause");return 0;}}1.3运行示例1.4数据分析(单次录入数据具有较大随机误差,只看增长趋势)问题规模(n)排序总复杂度规模(T(n))插入排序合并排序快速排序10 57 105 5020 221 280 12230 367 461 23840 946 660 37150 1394 879 43280 3261 1570 856100 4694 2064 1064200 22912 4718 2447500 130133 13668 73681000 504254 30309 1700310000 43898103 401968 225489根据列表分析,插入算法平均复杂度为, 合并算法平均复杂度为, 快速排序算法平均复杂度为,但是排序算法最坏情况下复杂度仍为,为了验证这一点,取n=1000的已排好数组,快排总规模变为503497,取n=10000的已排好数组,快排总规模变为50034997。
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;}教师评语:成绩:√优良中及格不及格算法实验报告二动态规划法实验。
实验报告
合肥师范学院实验报告册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。
《算法设计与分析》课程实验报告 (分治法(三))
《算法设计与分析》课程实验报告实验序号: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、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
算法分析与设计实验报告
第 1 次实验
if(maxi>maxj)
max=maxi;
else
max=maxj;
if(mini<minj)
min=mini;
else
min=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;
else
max=maxj;
if(mini<minj)
min=mini;
else
min=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); }。