实验三分治算法.doc

合集下载

算法设计与分析实验三

算法设计与分析实验三

实验三分治算法(2)一、实验目的与要求1、熟悉合并排序算法(掌握分治算法)二、实验题1、问题陈述:对所给元素存储于数组中和存储于链表中两中情况,写出自然合并排序算法.2、解题思路:将待排序元素分成大小大相同的两个集合,分别对两个集合进行排序,最终将排好序的子集合合并成为所要求的排好序的集合.自然排序是通过一次扫描待排元素中自然排好序的子数组,再进行子数组的合并排序.三、实验步骤程序代码:#include <iostream.h>const int N=100;//定义不可变常量N//各个函数的声明void ScanTarget(int target[], int n, int head[], int tail[]);int CountHead(int head[]);void MergeSort(int a[], int head[], int tail[], int m);void MergePass(int x[], int y[], int s, int a[], int b[], int m);void Merge(int c[], int d[], int l, int m, int r);//主函数的定义void main(){char a;do{int target[N],head[N],tail[N];int i=0,n,m;for(; i<N; i++){head[i]=-1;tail[i]=-1;}cout<<"请输入需要排序的数列的总数:"<<endl;cin>>n;cout<<"请输入需要排序的数列:" <<endl;for(i=0; i<n; i++)cin>>target[i];ScanTarget(target,n,head,tail);m=CountHead(head);//调用求长度的函数MergeSort(target,head,tail,m);//调用归并排序函数cout<<"排序后:"<<endl;for(i=0; i<n; i++)cout<<target[i]<<" ";cout<<endl;cout<<"是否继续(y/n):"<<endl;cin>>a;}while(a!='n' && a!='N');}void ScanTarget(int target[], int n, int head[], int tail[])//定义扫描待排数组的函数;{int i,j=0,k=0;head[k]=0;k++;for(i=1;i<n;i++){if(target[i-1]>target[i]){tail[j++]=i-1;head[k++]=i;}}tail[j]=n-1;}int CountHead(int head[])//定义求长度的函数;{int i(0);while(head[i]!=-1){i++;}return i;//返回长度值}void MergeSort(int a[], int head[], int tail[], int m)//定义归并排序算法{int b[N];int s=1;while(s<m){MergePass(a,b,s,head,tail,m);s+=s;MergePass(b,a,s,head,tail,m);s+=s;}}void MergePass(int x[], int y[], int s, int a[], int b[], int m)//合并输出{int i=0;while(i <= m-2*s){Merge(x,y,a[i],b[i+s-1],b[i+2*s-1]);i=i+2*s;}if(i+s < m){Merge(x,y,a[i],b[i+s-1],b[m-1]);}else{for(int j=i; j<m; j++)for(int k=a[j]; k<=b[j]; k++)y[k]=x[k];}}void Merge(int c[], int d[], int l, int m, int r)//合并已经排序的两个数组,即归并操作{int i,j,k;i=l;j=m+1;k=l;while((i<=m) && (j<=r)){if( c[i] <= c[j] )d[k++]=c[i++];else d[k++]=c[j++];}if( i>m ){for(int q=j; q<=r; q++)d[k++]=c[q];}else{for(int q=i; q<=m; q++)d[k++]=c[q];}}程序运行结果如下所示:请输入需要排序的数列的总数:5请输入需要排序的数列:13 78 34 5 66排序后:5 13 34 66 78是否继续(y/n):nPress any key to continue。

3分治法

3分治法

二分搜索算法分析
• 时间复杂度分析: 1 若n=1 C(n)= C( n / 2 )+1 若n ≥ 2 求解递推式得:
c(n) = log n + 1
6.3 合并排序
• 原问题:对A[1...n]排序 • 用分治策略分析: (1)划分:将A[1...n]分为A[1...n/2] A[n/2+1...n]两部分; (2)治理: 分别对A[1...n/2] 和 A[n/2+1...n]排序 (3)组合:将两个有序子序列合并为一 个有序序列
合并排序算法分析
• 时间复杂度分析: 0 若n=1 C(n)= 2C( n / 2 )+n-1 若n≥2 求解递推式得: C(n)=nlogn-n+1
思考题:求数组的“逆序对” 思考题:求数组的“逆序对”个 数
• Sort公司是一个专门为人们提供排序服务的公 司,该公司的宗旨是“顺序是最美丽的”。 他们的工作是通过一系列移动,将某些物品 按顺序摆好。他们的服务是通过工作量来计 算的,即移动东西的次数。所以,在工作前 必须先考察工作量,以便向用户提出收费数 目。 • 用户并不需要知道精确的移动次数,实际上, 大多数人是凭感觉来认定这一列物品的混乱 程度。
分治法的基本步骤
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); //将各子问题的解合并为原问题的解 } 人们从大量实践中发现,在用分治法设计算法时, 最好使子问题的规模大致相同。即将一个问题分成 大小相等的k个子问题的处理方法是行之有效的。 这种使子问题规模大致相等的做法是出自一种平衡 平衡 (balancing)子问题 子问题的思想,它几乎总是比子问题 子问题 规模不等的做法要好。

实验三 分治算法

实验三 分治算法

实验三分治算法(4学时)
一、实验目的与要求
1、熟悉二分搜索算法和快速排序算法;
2、初步掌握分治算法;
二、实验题
1、设a[0:n-1]是一个已排好序的数组。

请改写二分搜索算法,使得当搜索元素x不在数组中时,返回小于x的最大元素的位置i和大于x的最小元素位置j。

当搜索元素在数组中时,I和j相同,均为x在数组中的位置。

设有n个不同的整数排好序后存放于t[0:n-1]中,若存在一个下标i,0≤i<n,使得t[i]=i,设计一个有效的算法找到这个下标。

要求算法在最坏的情况下的计算时间为O(logn)。

2、在快速排序中,记录的比较和交换是从两端向中间进行的,关键字较大的记录一次就能交换到后面单元,关键字较小的记录一次就能交换到前面单元,记录每次移动的距离较大,因而总的比较和移动次数较少。

三、实验提示
1、用i,j做参数,且采用传递引用或指针的形式带回值。

2、。

分治算法的实验报告

分治算法的实验报告

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

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

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

二、实验目的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. 合并排序合并排序是一种稳定的排序算法,其基本思想是将待排序序列分为两个子序列,分别对两个子序列进行排序,然后将排序后的子序列合并为一个有序序列。

分治算法实验报告

分治算法实验报告

算法分析与设计实验报告第 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

分治算法实验报告.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;}。

分治算法实验(用分治法查找数组元素的最大值和最小值)

分治算法实验(用分治法查找数组元素的最大值和最小值)

算法分析与设计实验报告第一次实验附录:完整代码(分治法)#include<iostream>#include<time.h>#include<iomanip>using namespace std;//当数组中的元素个数小于3时,处理最大值int compmax(int A[],int start,int end){int max;if(start<end) //有两个元素{if(A[start]<=A[end])max=A[end];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])min=A[start];elsemin=A[end];}else//有一个元素min=A[start];return min;}//分治法处理整个数组,求最大值与最小值void merge(int a[],int left,int right,int &Max,int &Min) //Max,Min用来保存最大值与最小值//之所以使用&引用,是由于如果只是简单的使用变量,并不会改变Max与Min的值,使用指针也可以{int max1=0,min1=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与Min中Max=max1;elseMax=max2;if(min1<=min2)Min=min1;elseMin=min2;}else//数组中元素个数小于3时的情况,直接赋值{Max=compmax(a,left,right);Min=compmin(a,left,right);}}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 main(){int n;int i;int max;int min;cout<<"请输入要查找的序列个数:"<<endl;for(i=0;i<5;i++){cin>>n;ran(a,n);clock_t start,end,over; //计算程序运行时间的算法start=clock();end=clock();over=end-start;start=clock();merge(a,0,n-1,max,min); //调用分治法算法cout<<max<<" "<<min<<endl;end=clock();printf("The time is %6.3f",(double)(end-start-over)/CLK_TCK); //显示运行时间}system("pause"); //停止运行窗口return 0;}完整代码(非递归方法)#include<iostream>#include<time.h>#include<iomanip>using namespace std;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 main(){int max=a[0],min=a[0];int i,j,n;cout<<"请输入数据规模:"<<endl;for(j=0;j<5;j++){cin>>n;ran(a,n);clock_t start,end,over; //计算程序运行时间的算法start=clock();end=clock();over=end-start;start=clock();for(i=1;i<n;i++){if(a[i]>max)max=a[i];if(a[i]<min)min=a[i];}cout<<max<<" "<<min<<endl;end=clock();printf("The time is %6.3f",(double)(end-start-over)/CLK_TCK); //显示运行时间}system("pause");return 0;}。

分治法实验报告

分治法实验报告

分治法实验报告分治法实验报告一、引言分治法是一种重要的算法设计策略,它将一个大问题分解成若干个小问题,并通过递归的方式解决这些小问题,最终将它们的解合并起来得到原问题的解。

本实验旨在通过实际案例,探索分治法的应用和效果。

二、背景在计算机科学领域,分治法常常被用于解决一些复杂的问题,如排序、搜索、图算法等。

它的核心思想是将问题划分为更小的子问题,然后分别解决这些子问题,最后将它们的解合并起来得到原问题的解。

通过这种方式,我们可以降低问题的复杂度,提高算法的效率。

三、实验目的本实验旨在通过实际案例,验证分治法在问题解决中的有效性,并探索其在不同问题上的应用效果。

通过对比不同算法的运行时间和结果准确性,评估分治法在不同场景下的适用性。

四、实验过程本次实验选取了两个典型的问题,分别是最大子数组和快速排序。

首先,我们使用分治法来解决最大子数组问题。

该问题要求在一个给定的数组中,找到一个连续子数组,使得该子数组的和最大。

我们将数组分为两半,分别求解左半部分和右半部分的最大子数组,然后再考虑跨越中点的最大子数组。

通过递归的方式,最终得到整个数组的最大子数组。

接着,我们使用分治法来实现快速排序算法。

快速排序是一种高效的排序算法,它的核心思想是通过选择一个基准元素,将数组分为两个部分,使得左边的元素都小于等于基准元素,右边的元素都大于等于基准元素。

然后,对左右两个部分分别递归地进行快速排序,最终得到有序的数组。

五、实验结果通过对最大子数组和快速排序问题的实验,我们得到了以下结果。

首先,分治法在解决最大子数组问题上表现出色。

通过将问题划分为更小的子问题,我们可以在较短的时间内找到最大子数组,大大提高了算法的效率。

其次,在快速排序问题上,分治法同样展现了强大的能力。

通过不断地划分数组并进行排序,我们可以快速得到有序的结果。

六、实验分析分治法作为一种重要的算法设计策略,具有许多优点。

首先,它可以将复杂的问题分解为简单的子问题,降低了问题的复杂度,提高了算法的效率。

实验三 分治与贪心lu

实验三  分治与贪心lu

实验三分治与贪心一、实验目的与要求熟悉C/C++语言的集成开发环境;通过本实验加深对分治法、贪心算法的理解。

二、实验内容:掌握分治法、贪心算法的概念和基本思想,并结合具体的问题学习如何用相应策略进行求解的方法。

三、实验题1. 【循环赛日程安排问题】计算机学院准备举办一次男生羽毛球单打比赛,现在总共有16名选手报名,首轮比赛准备采取循环赛的形式进行角逐,要求必须在15天内比完,且每个选手每天只能安排一场比赛,请你帮助学生会安排首轮循环赛的比赛日程表。

2.【找零钱问题】一个小孩买了价值为33美分的糖,并将1美元的钱交给售货员。

售货员希望用数目最少的硬币找给小孩。

假设提供了数目有限的面值为25美分、10美分、5美分、及1美分的硬币。

给出一种找零钱的贪心算法。

四、实验步骤理解算法思想和问题要求;编程实现题目要求;上机输入和调试自己所编的程序;验证分析实验结果;整理出实验报告。

五、实验程序【循环赛日程安排问题】#include<iostream>#include<STDIO.H>void Table(int k) {int a[20][20];int q,n=1;for(int i=1;i<=k;i++)n*=2; q=n;for( i=1;i<=n;i++)a[1][i]=i;int m=1;for(int s=1;s<=k;s++) {n/=2; for(int t=1;t<=n;t++)for( i=m+1;i<=2*m;i++)for(int j=m+1;j<=2*m;j++) {a[i][j+(t-1)*m*2]=a[i-m][j+(t-1)*m*2-m];a[i][j+(t-1)*m*2-m]=a[i-m][j+(t-1)*m*2]; }m*=2; }for( i=1;i<=q;i++) {for(int j=1;j<=q;j++) printf("%d ",a[i][j]);printf("\n"); }}void main(){ int k=4; Table(k); system("pause"); }【找零钱问题】#include<iostream>using namespace std;int main() {int s=100-33; int a=25; int b=10; int c=5;int d=1; int cout1=0; int cout2=0;int cout3=0; int cout4=0;for(s;s>=a;cout1++)s=s-a;for(s;s>=b;cout2++)s=s-b;for(s;s>=c;cout3++)s=s-c;for(s;s>=d;cout4++)s=s-d;if(s==0){ cout<<"找"<<cout1<<"个25 美分的硬币"<<endl; cout <<"和"<<cout2<<"个10 美分的硬币"<<endl;cout <<"和"<<cout3<<"个5 美分的硬币"<<endl;cout<<"和"<<cout4<<"个1 美分的硬币"<<endl; } system("pause");return 0; }六、实验结果【循环赛日程安排问题】.【找零钱问题】七、实验分析实验分析分治法的设计思想是,将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。

分治法实验报告详细

分治法实验报告详细

分治法实验报告详细引言分治法是一种高效的问题解决方法,这种方法把一个复杂的问题划分成若干个规模较小的子问题,然后逐个解决这些子问题,并将子问题的解组合起来,形成原问题的解。

在本实验中,我们将通过实际案例来演示和验证分治法的有效性和高效性。

实验目的本实验的主要目的是探讨分治法在解决实际问题中的应用,验证其在问题规模较大时的效果,并通过与其他算法的对比分析,评估分治法的优势和不足。

实验材料与方法我们选择了一个具体的实际问题作为案例:在一个包含n个元素的列表中,查找特定元素x的位置。

为了模拟问题的规模,我们首先生成了一个包含1000个随机整数的列表,然后从中随机选择一个元素作为我们要查找的目标x。

我们采用了如下的分治法解决方案:1. 将列表分成两个子列表,分别包含前半部分和后半部分的元素。

2. 如果目标元素x等于列表的中间元素,则返回中间元素的位置。

3. 如果目标元素x小于列表的中间元素,则递归调用步骤1,查找前半部分子列表中的目标元素x。

4. 如果目标元素x大于列表的中间元素,则递归调用步骤1,查找后半部分子列表中的目标元素x。

5. 如果子列表为空,则说明目标元素x不存在于列表中。

实验结果与分析我们依次使用二分查找法和分治法来解决上述问题,并记录它们的运行时间。

重复实验10次,并计算它们的平均运行时间。

实验结果如下:- 二分查找法平均运行时间:0.002秒- 分治法平均运行时间:0.001秒通过实验数据可以看出,分治法的运行时间明显优于二分查找法。

这是因为分治法通过将问题划分为更小的子问题,使得每个子问题的规模减小,从而减少了解决每个子问题的时间。

而二分查找法则只是将问题逐步缩小,没有有效地利用子问题之间的联系。

结论通过本实验,我们验证了分治法在解决实际问题中的有效性和高效性。

与其他算法相比,分治法在处理问题规模较大时表现出更好的性能。

因此,我们可以得出结论,对于复杂问题的解决,分治法是一种值得采用的优秀方法。

分治算法使用实例

分治算法使用实例

分治算法使用实例分治算法是一种基本的算法思想,用于解决各种问题。

它将一个大问题分解成多个小问题,然后递归地解决这些小问题,并将结果进行合并,从而得到大问题的解决方案。

分治算法被广泛应用于各个领域,如排序、查找、计算、图像处理等。

下面以三个经典的分治算法为例,具体说明分治算法的使用场景和实现方法。

1.归并排序:归并排序是一种高效的排序算法,它使用了分治算法的思想。

该算法将待排序的数组不断地二分,直到问题被分解为最小规模的子问题。

然后,将这些子问题逐个解决,并将结果进行合并,即将两个有序的子数组合并为一个有序的数组。

最终,所有子问题都解决完毕后,得到的数组就是排序好的结果。

归并排序的实现过程如下:-分解:将待排序的数组分解为两个子数组,递归地对这两个子数组进行排序。

-解决:对两个子数组分别进行排序,可以使用递归或其他排序算法。

-合并:将两个已排序的子数组合并为一个有序的数组。

2.求解最大子数组和:给定一个整数数组,求其最大子数组和。

分治算法可以解决这个问题。

该算法将问题分解为三个子问题:最大子数组和位于左半部分、最大子数组和位于右半部分、最大子数组和跨越中间位置。

然后,递归地对这三个子问题求解,并将结果进行合并,得到最终的解。

求解最大子数组和的实现过程如下:-分解:将待求解的数组分解为两个子数组,递归地求解这两个子数组的最大子数组和。

-解决:对两个子数组分别求解最大子数组和,可以使用递归或其他方法。

-合并:找出三个子问题中的最大子数组和,返回作为最终的解。

3.汉诺塔问题:汉诺塔问题是一个著名的递归问题,可以使用分治算法解决。

假设有三个柱子,初始时,有n个盘子从小到大依次放在第一个柱子上。

目标是将这些盘子移动到第三个柱子上,并保持它们的相对顺序不变。

每次只能移动一个盘子,并且大盘子不能放在小盘子上面。

汉诺塔问题的实现过程如下:-分解:将问题分解为两个子问题,将n-1个盘子从第一个柱子移动到第二个柱子,将最大的盘子从第一个柱子移动到第三个柱子。

分治算法实验(用分治法实现归并排序算法)

分治算法实验(用分治法实现归并排序算法)

实 验 比 较 实 验 得 分
附录: 完整代码(分治法)
#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页)

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;}教师评语:成绩:√优良中及格不及格算法实验报告二动态规划法实验。

实验三(分治算法)

实验三(分治算法)

华东师范大学计算机科学技术系上机实践报告课程名称:算法设计与分析年级:05上机实践成绩:指导教师:柳银萍姓名:上机实践名称:分治算法学号:上机实践日期:2007-4-24上机实践编号:NO.3组号:上机实践时间:10:00-11:30一、目的二、内容与设计思想1.在一个数组A[1..n] 中,同时寻找最大值和最小值[假设n 为2 的方幂]。

并给出你的算法的复杂度分析。

要求:输入:第一行为一个正整数N(0<N<=500000),表示数组中有多少个元素,当N<=0时表示输入结束。

接下来一行中有N个数。

表示数组A中的元素,这些数不超过65535。

输出:输出最大元素和最小元素,输出见sample。

每个Case之间用一个空行隔开。

1.1其思路是:1.2具体算法是:1.3其复杂度分析2.给出一个分治算法,在一个具有n 个数的数组中找出第二个最大元素。

要求:输入:第一行为一个正整数N(0<N<=500000),表示数组中有多少个元素,当N<=0时表示输入结束。

接下来一行中有N个数,表示数组A中的元素,这些数不超过65535。

输出:输出第二个最大元素,每一个输出占一行。

2.1其思路是:2.2具体算法是:3.给出一个分治算法,计算两个n 位大整数的乘积。

即A*B.并给出你的算法的复杂度分析。

要求:输入:输入有多组测试数据,每个输入占两行,第一行表示整数A,第二行表示整数B。

.输出:输出A*B。

3.1其思路是:3.2具体算法是:3.3其复杂度分析:三、使用环境四、调试过程五、总结六、附录1. 求最值问题的程序:(此处放程序)运行结果:2. 求次最大值问题的程序:(此处放程序)运行结果:3.大整数乘积问题的程序:(此处放程序)运行结果:要求至少给出1组测试数据运行结果。

分治与贪心

分治与贪心

实验三分治与贪心一、实验目的与要求熟悉C/C++语言的集成开发环境;通过本实验加深对分治法、贪心算法的理解。

软件环境:操作系统:windows7 旗舰版集成开发环境:visual studio 2010 旗舰版硬件环境:处理器:因特尔Core i3 M 380内存:2GB二、实验内容:掌握分治法、贪心算法的概念和基本思想,并结合具体的问题学习如何用相应策略进行求解的方法。

三、实验题1. 【循环赛日程安排问题】计算机学院准备举办一次男生羽毛球单打比赛,现在总共有16名选手报名,首轮比赛准备采取循环赛的形式进行角逐,要求必须在15天内比完,且每个选手每天只能安排一场比赛,请你帮助学生会安排首轮循环赛的比赛日程表。

2.【找零钱问题】一个小孩买了价值为33美分的糖,并将1美元的钱交给售货员。

售货员希望用数目最少的硬币找给小孩。

假设提供了数目有限的面值为25美分、10美分、5美分、及1美分的硬币。

给出一种找零钱的贪心算法。

四、实验步骤理解算法思想和问题要求;编程实现题目要求;上机输入和调试自己所编的程序;验证分析实验结果;整理出实验报告。

五、实验程序实验1:#include<iostream>using namespace std;void dump(int *arr, int len);//输出比赛安排详情void game(int *team, int len, int id);//分治法安排比赛void game(int *team, int len, int id){//id为第id轮的安排int base = 2;while (id > len/base){id -= len/base;base <<= 1;}for (int i=0; i<base/2; ++i){int start = i+base/2+(id-1)*base;for (int j=0; j<len/base; ++j){team[i*2*len/base+2*j] = base*j+i;team[i*2*len/base+2*j+1] = (start+base*j)%len;}}}//显示分组情况void dump(int *arr, int len){for(int i=0;i<len;i+=2)//i+2则是对偶数号选手固定,奇数号选手配对 printf("%02d-%02d ", arr[i], arr[i+1]);cout<<endl;}int main(){const int len = 16; //设置参赛人数为16人int team[len]; //每一轮安排好的选手组合for (int i=1; i<len; ++i){game(team, len, i); //分治法安排比赛printf("[%02d] ", i);//显示比赛时间天dump(team, len); //输出比赛安排详情}system("pause");return 0;}实验2:#include<iostream>using namespace std;int main(){int allmoney=100; //顾客付的钱int needmoney=33; //收银需要的钱int backmoney=0; //要找回给顾客的钱int money[100]={0}; //找钱的组合方式int i=0; //循环控制数组下表变换backmoney=allmoney-needmoney;while(backmoney) //当要找的钱为0时循环结束{ if(backmoney>=25)//优先考虑找25元是否大于0{money[i]=25; //向找钱组合添加一个25backmoney-=25;//要找回顾客的钱扣除25元}else if(backmoney>=10){money[i]=10;backmoney-=10;}else if(backmoney>=5){money[i]=5;backmoney-=5;}else if(backmoney>=1){money[i]=1;backmoney-=1;}i++;}cout<<"贪心法求的要找回钱组合为:"<<endl;for(int j=0;money[j]!=0;j++)cout<<money[j]<<" ";cout<<endl;system("pause");return 0;}六、实验结果实验1:实验2:七、实验分析实验一的核心就是每次把组内奇数和偶数号码的选手分开成两组,再把本次分组分开的小组又编号奇数和偶数,再把奇数号码合并一组,偶数号码合并一组,一步步往下分,直到最后只有两个选手为止。

实验报告

实验报告

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

华东师范大学计算机科学技术系上机实践报告
课程名称:算法设计与分析年级:05上机实践成绩:
指导教师:柳银萍姓名:
上机实践名称:分治算法学号:上机实践日期:2007-4-24
上机实践编号:NO.3组号:上机实践时间:10:00-11:30
一、目的
二、内容与设计思想
1.在一个数组A[1..n] 中,同时寻找最大值和最小值[假设n 为2 的方幂]。

并给出你的算法的复杂度分析。

要求:
输入:第一行为一个正整数N(0<N<=500000),表示数组中有多少个元素,当N<=0时表示输入结束。

接下来一行中有N个数。

表示数组A中的元素,这些数不超过65535。

输出:输出最大元素和最小元素,输出见sample。

每个Case之间用一个空行隔开。

1.1其思路是:
1.2具体算法是:
1.3其复杂度分析
2.给出一个分治算法,在一个具有n 个数的数组中找出第二个最大元素。

要求:
输入:第一行为一个正整数N(0<N<=500000),表示数组中有多少个元素,当N<=0时表示输入结束。

接下来一行中有N个数,表示数组A中的元素,这些数不超过65535。

输出:输出第二个最大元素,每一个输出占一行。

2.1其思路是:
2.2具体算法是:
3.给出一个分治算法,计算两个n 位大整数的乘积。

即A*B.并给出你的算法的复杂度分
析。

要求:
输入:输入有多组测试数据,每个输入占两行,第一行表示整数A,第二行表示整数B。

.
输出:输出A*B。

3.1其思路是:
3.2具体算法是:
3.3其复杂度分析:
三、使用环境
四、调试过程
五、总结
六、附录
1. 求最值问题的程序:
(此处放程序)
运行结果:
2. 求次最大值问题的程序:
(此处放程序)
运行结果:
3.大整数乘积问题的程序:
(此处放程序)
运行结果:
要求至少给出1组测试数据运行结果。

相关文档
最新文档