算法设计 第4章 分治法文档格式.docx

上传人:b****2 文档编号:1462331 上传时间:2023-04-30 格式:DOCX 页数:19 大小:18.69KB
下载 相关 举报
算法设计 第4章 分治法文档格式.docx_第1页
第1页 / 共19页
算法设计 第4章 分治法文档格式.docx_第2页
第2页 / 共19页
算法设计 第4章 分治法文档格式.docx_第3页
第3页 / 共19页
算法设计 第4章 分治法文档格式.docx_第4页
第4页 / 共19页
算法设计 第4章 分治法文档格式.docx_第5页
第5页 / 共19页
算法设计 第4章 分治法文档格式.docx_第6页
第6页 / 共19页
算法设计 第4章 分治法文档格式.docx_第7页
第7页 / 共19页
算法设计 第4章 分治法文档格式.docx_第8页
第8页 / 共19页
算法设计 第4章 分治法文档格式.docx_第9页
第9页 / 共19页
算法设计 第4章 分治法文档格式.docx_第10页
第10页 / 共19页
算法设计 第4章 分治法文档格式.docx_第11页
第11页 / 共19页
算法设计 第4章 分治法文档格式.docx_第12页
第12页 / 共19页
算法设计 第4章 分治法文档格式.docx_第13页
第13页 / 共19页
算法设计 第4章 分治法文档格式.docx_第14页
第14页 / 共19页
算法设计 第4章 分治法文档格式.docx_第15页
第15页 / 共19页
算法设计 第4章 分治法文档格式.docx_第16页
第16页 / 共19页
算法设计 第4章 分治法文档格式.docx_第17页
第17页 / 共19页
算法设计 第4章 分治法文档格式.docx_第18页
第18页 / 共19页
算法设计 第4章 分治法文档格式.docx_第19页
第19页 / 共19页
亲,该文档总共19页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

算法设计 第4章 分治法文档格式.docx

《算法设计 第4章 分治法文档格式.docx》由会员分享,可在线阅读,更多相关《算法设计 第4章 分治法文档格式.docx(19页珍藏版)》请在冰点文库上搜索。

算法设计 第4章 分治法文档格式.docx

j<

j++)

cout<

a[j]<

"

endl;

m=Max(a,0,n-1);

a[m]<

return0;

}

intMax(inta[],intlow,inthigh)

intmid,max,max1,max2;

if(low==high)returnlow;

else

{

mid=(low+high)/2;

max1=Max(a,low,mid);

max2=Max(a,mid+1,high);

max=a[max1]>

a[max2]?

max1:

max2;

returnmax;

}

设计分治算法,实现将数组A[n]中所有的元素循环左移k个位置,要求时间

复杂度为,空间复杂度为,例如,对abcdefgh循环左移3位得到defghabc.

将数组元素左移n块,则将数组分成几块,然后将每一块进行编号,

然后进行移动,序号相同的,前一段序号的那个数移到后一段序号的那个数即可。

1.实现相邻两端相同编号的数进行移动

2.k个函数调用实现每个序号的书都进行移动

3.输出数组

*/

voidConverse(char*A,intn,intk);

voidReverse(char*A,intfrom,intto);

{

charA[100];

intk;

请输入数组:

A;

请输入左移的位数k:

k;

Converse(A,strlen(A),k);

voidReverse(char*A,intfrom,intto)

for(inti=0;

i<

(to-from+1)/2;

i++)

{

chartemp=A[from+i];

A[from+i]=A[to-i];

A[to-i]=temp;

voidConverse(char*A,intn,intk)

Reverse(A,0,k-1);

Reverse(A,k,n-1);

Reverse(A,0,n-1);

移动后的数组为:

A[i];

在有序序列(r1,r2,r3·

·

rn)中,存在序号i(1<

=i<

=n),

使得ri=i;

请设计一个分治算法找到这个元素,要求算法在最坏的情况下的

时间性能为O(log2n);

这道题主要采用的是折半查找的思路,同时也体现出了分治法;

把一个大的问题折半折半再折半·

的处理,最终就可以找到目标。

1.输入数组

2.定义折半查找的函数;

2.1.折半找到中间的数比较r[i]和i的大小;

2.2.如果r[i]>

i则我们就直接在数组的左边找;

否则就在右边找。

2.3.找到目标输出;

#include<

voidf(inta[],intn);

intmain()

inta[1001];

inti,n;

请输入有序数组的个数:

for(i=0;

cin>

a[i];

f(a,n);

voidf(inta[],intn)

intleft=0,right=n-1,mid;

while(left<

right)

mid=(left+right)/2;

if(a[mid]=mid)

{

cout<

这个元素是:

a[mid]<

break;

}

elseif(a[mid]>

mid)

right=mid;

else

left=mid;

在一个序列中出现次数最多的元素称为众数,

请设计算法寻找众数并分析算法的时间复杂性;

题目要求是要用分治法,那我们就只有在排序上用分治法,

将数组用快速排序,之后再遍历一次数组我们就可以找到众数。

此时算法的时间复杂性为nlog(n);

1.输入数组;

2.对数组进行快速排序

3.for循环遍历数组,用if判断找出众数

4.输出众数。

intPartition(intr[],intfirst,intend);

voidQuickSort(intr[],intfirst,intend);

intr[10001];

intn,cont=0,max=0,temp;

请输入数组的元素:

j++)

r[j];

QuickSort(r,0,n-1);

intk=i+1;

while(r[i]==r[k]&

&

i<

n)

cont++;

i++;

if(cont>

max)

{

temp=i-1;

max=cont;

cont=0;

i=i-1;

众数是:

r[temp]<

重复的次数是:

max<

//for(inti=0;

//cout<

r[i]<

//cout<

intPartition(intr[],intfirst,intend)//划分

inti=first,j=end;

//初始化待划分区间

while(i<

j)

j&

r[i]<

=r[j])j--;

//右侧扫描

if(i<

j){

inttemp=r[i];

r[i]=r[j];

r[j]=temp;

//将较小记录交换到前面

i++;

=r[j])i++;

//左侧扫描

j){

//将较大记录交换到后面

j--;

returni;

//返回轴值记录的位置

voidQuickSort(intr[],intfirst,intend)//快速排序

intpivot;

if(first<

end){

pivot=Partition(r,first,end);

//划分,pivot是轴值在序列中的位置

QuickSort(r,first,pivot-1);

//求解子问题1,对左侧子序列进行快速排序

QuickSort(r,pivot+1,end);

//求解子问题2,对右侧子序列进行快速排序

}

设M是一个n×

n的矩阵,其中每行的元素从左到右单增有序,

每列的元素从上到下单增有序。

给出一个分治算法计算出给定元素x

在M中的位置或者表明x不在M中。

分析算法的时间复杂性。

在n×

n的矩阵中其中每行的元素从左到右单增有序,每列的元素从上到下单增有序。

那么我们就可以找到矩阵的中心元素对其进行比较,比较后要找的元素可能有两块区域,

再对这两块区域再进行递归调用就可以找到我们想要的元素。

输出元素是否存在及其位置。

1,调用MatrixBinary函数

2.1每次都找到中心元素

2.2用要查找的元素与之进行比较

2.3如果比中心元素大就在其右侧或左下角反之在其左侧或者右上角

2.4继续递归调用MatrixBinary

2.5找到了返回1,否则返回0;

3.输出。

intM[5][5]=

{1,2,3,4,5},

{6,7,8,9,10},

{11,12,13,14,15},

{16,17,18,19,20},

{21,22,23,24,25}

};

intx=19;

intMatrixBinary(intM[5][5],intrb,intre,intcb,intce)

intrm=(rb+re)/2;

intcm=(cb+ce)/2;

if(rb>

re||cb>

ce)

if(x==M[rm][cm])

x<

所在的位置:

M["

rm<

]["

cm<

]"

return1;

elseif(rb==re&

cb==ce)

if(x>

M[rm][cm])

returnMatrixBinary(M,rb,re,cm+1,ce)||MatrixBinary(M,rm+1,re,cb,cm);

else

returnMatrixBinary(M,rb,rm-1,cb,ce)||MatrixBinary(M,rm,re,cb,cm-1);

}

intmain()

inta=MatrixBinary(M,0,4,0,4);

if(a==1)

要查找的"

存在"

不存在"

将数组用快速排序,之后再遍历一次数组我们就可以找到s1,s2。

3.for循环遍历数组,找到s1,s2

4.输出两个子集元素之和的最大差。

intn,s1=0,s2=0,c;

intk=n/2;

k;

s1=s1+r[i];

for(intq=k;

q<

q++)

s2=s2+r[q];

c=s2-s1;

两个子集元素之和的最大差是:

c<

循环赛日程安排问题:

设有n=2^k个运动员要进行网球循环赛。

现要设计一个满足以下要求的比赛日程表:

(1)每个选手必须与其他n-1个选手各赛一次;

(2)每个选手一天只能参赛一次;

先用2个选手模拟,再用4个选手模拟找到其中相似之处:

日程表划分为四小块,左下小块可以用左上小块的每个数相加同一个数;

右上角的数和左下角的数是一样的;

右下角的数和左上角的数是一样的。

我们找到它们的位置关系就可以把日程表表示出来;

注:

第一列表示选手的人数,第二列表示第一天,依次类推。

在表中的第i行,第j列处填入第i个选手在第j天所遇到的选手

K=2时:

1234

2143

3412

4321

k=3时:

12345678

21436587

34127856

43218765

56781234

65872143

78563412

87654321

1.输入K;

2.创建动态二维数组

3.日程函数:

3.1填左下角

3.2填右上角

3.3填右下角

4.输出日程表;

voidTable(intk,int**a);

intn=1;

for(intj=1;

=k;

j++)//参加比赛选手的人数

n=n*2;

int**a=newint*[n+1];

//根据n动态分配二维数组a

=n;

a[i]=newint[n+1];

Table(k,a);

//分配日程函数

for(intq=1;

q<

=n;

q++)

for(intl=1;

l<

l++)

a[q][l]<

for(intr=0;

r<

r++)//释放空间

delete[]a[r];

delete[]a;

voidTable(intk,int**a)

inti,j,t,temp;

intn=2;

a[1][1]=1;

a[1][2]=2;

//最开始只有两个人比赛的安排

a[2][1]=2;

a[2][2]=1;

for(t=1;

t<

t++)

temp=n;

n=n*2;

for(i=temp+1;

i++)//填左下角的元素

for(j=1;

=temp;

a[i][j]=a[i-temp][j]+temp;

for(i=1;

i++)//填右上角的元素

for(j=temp+1;

a[i][j]=a[i+temp][(j+temp)%n];

for(i=temp+1;

i++)//填右下角的元素

for(j=temp+1;

a[i][j]=a[i-temp][j-temp];

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 总结汇报 > 学习总结

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2