《算法设计与分析》实验二.docx
《《算法设计与分析》实验二.docx》由会员分享,可在线阅读,更多相关《《算法设计与分析》实验二.docx(11页珍藏版)》请在冰豆网上搜索。
《算法设计与分析》实验二
《算法设计与分析》实验二
学号1421050102
天津城建大学
《算法设计与分析》
实验报告二
学生姓名
Cherish
专业、班级
地理
指导教师
唐国峰
成绩
计算机与信息工程学院软件工程系
2017年3月28日
四、实验过程
(一)题目一:
对用户输入的杂乱无序的数字序列按照由小到大的顺序排序:
快速排序
题目分析
快速排序是冒泡排序的改进,以一组杂乱无序的数字最左边为枢轴记录的关键字,最右侧指针若比关键字大,则右侧指针左移,若出现比它小的交换两指针指向数的排序完成。
算法实现
#include
#include
voidquickSort(inta[],intl,intr)
{
inti,j,t;
i=l;j=r;
t=a[l];//枢轴元素t为数组最左侧的元素
if(l>r)
return;
while(i!
=j)//i往右移动j往左移动当指向同一位置时扫描完成
{
while(a[j]>=t&&j>i)
j--;//如果右侧指针元素比轴测元素大,指针元素左移
if(j>i)//确保i在j左边
a[i++]=a[j];//当右侧指针元素比轴测元素小时,交换两指针指向数的位置
while(a[i]<=t&&j>i)
i++;//如果左侧指针元素比轴测元素小,指针元素右移
if(j>i)//确保i在j左边
a[j--]=a[i];//当左侧指针元素比轴测元素大时,交换两指针指向数的位置
}
a[i]=t;
quickSort(a,l,i-1);//对左边进行排序
quickSort(a,i+1,r);//对右边进行排序
}
voidmain()
{
inti,n,f[100];
printf("请输入要比较数字的个数:
\n");
scanf_s("%d",&n);
for(i=0;i{
printf("请输入第%d个数字:
\n",i+1);
scanf_s("%d",&f[i]);
}
quickSort(f,0,n-1);
printf("快速排序的结果是:
\n");
for(i=0;iprintf("%d",f[i]);
printf("\n");
system("pause");
getchar();
}
运行结果
经验归纳
结合以前学的数据结构及应用算法,较容易理解。
题目二:
对用户输入的杂乱无序的数字序列按照由小到大的顺序排序:
合并排序
题目分析
合并排序的基本思想是:
将待排序的元素分成大小大相同的两个子集合,分别对两个子集合进行排序,最终将排序好的子集合合并成所要求的拍好序的集合。
算法构造
核心代码来自书上:
MergePass(Typex[],Typey[],ints,intn)//合并大小为s的相邻序列子数组
Merge(Typec[],Typed[],intl,intm,intr)//合并c[l,m]和x[m+1,r]到y[l,r]
算法实现
#include
#include
template
voidMergeSort(Typea[],intn)
{
Type*b=newType[n];
ints=1;
while(s{
MergePass(a,b,s,n);//将a中的元素合并到数组b
s+=s;
MergePass(b,a,s,n);//将b中的元素合并到数组a
s+=s;
}
}
template
voidMerge(Typec[],Typed[],intl,intm,intr)//合并c[l,m]和x[m+1,r]到y[l,r]
{
inti=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(intq=j;q<=r;q++)
d[k++]=c[q];
}
else
for(intq=i;q<=m;q++)
d[k++]=c[q];
}
template
voidMergePass(Typex[],Typey[],ints,intn){//合并大小为s的相邻序列子数组
inti=0;
while(i<=n-2*s)
{//合并大小为s的相邻2字段数组
Merge(x,y,i,i+s-1,i+2*s-1);//合并x[i,i+s-1]和x[i+s,i+2*s-1]到y[i,i+2*s-1]
i=i+2*s;
}
if(i+sMerge(x,y,i,i+s-1,n-1);
else
for(intj=i;j<=n-1;j++)
y[j]=x[j];
}
voidmain()
{
inta[100],i,n;
printf("请输入要进行合并排序的数字的个数:
\n");
scanf_s("%d",&n);
for(i=0;i{
printf("请输入要进行合并排序的第%d个数字:
\n",i+1);
scanf_s("%d",&a[i]);
}
MergeSort(a,n);
printf("合并排序的结果:
\n");
for(i=0;iprintf("%d,",a[i]);
printf("\n");
system("pause");
}
运行结果
经验归纳
结合以前学的数据结构及应用算法,用心理解还能明白。
题目三:
棋盘覆盖问题。
(要求N可由用户输入)
题目分析
将棋盘平分四部分,将分割后的再一分为四,一直分,直到含有特殊方格,看特殊方格在那一部分中,用一个L型股牌覆盖这3个较小棋盘会合处。
算法构造
算法实现
#include
#include
#include
intBoard[100][100];//用来存放棋盘元素的数组
inttile=1;//L型骨牌的投放序号
voidChessBoard(inttr,inttc,intdr,intdc,intsize)
{
if(size==1){//棋盘方格大小为,说明递归到最里层
return;
}
intt=tile++;//每次递增
ints=size/2;//分割棋盘
if(dr
ChessBoard(tr,tc,dr,dc,s);
}
else{//不在,将该子棋盘右下角的方块视为特殊方块
Board[tr+s-1][tc+s-1]=t;
ChessBoard(tr,tc,tr+s-1,tc+s-1,s);
}
if(dr
|
=tc+s){//检查特殊方块是否在右上角子棋盘中ChessBoard(tr,tc+s,dr,dc,s);
}
else{//不在,将该子棋盘左下角的方块视为特殊方块
Board[tr+s-1][tc+s]=t;
ChessBoard(tr,tc+s,tr+s-1,tc+s,s);
}
if(dr>=tr+s&&dcChessBoard(tr+s,tc,dr,dc,s);
}
else{//不在,将该子棋盘右上角的方块视为特殊方块
Board[tr+s][tc+s-1]=t;
ChessBoard(tr+s,tc,tr+s,tc+s-1,s);
}
if(dr>=tr+s&&dc>=tc+s){//检查特殊方块是否在右下角子棋盘中
ChessBoard(tr+s,tc+s,dr,dc,s);
}
else{//不在,将该子棋盘左上角的方块视为特殊方块
Board[tr+s][tc+s]=t;
ChessBoard(tr+s,tc+s,tr+s,tc+s,s);
}
}
voidmain()
{
intn;
intsize;//棋盘大小
printf("请输入一个数字,将为您创建2^n*2^n大小的棋盘:
");
scanf_s("%d",&n);
intx,y;
size=(int)pow(2.0,(int)n);
printf("输入特殊方格的横坐标:
");
scanf_s("%d",&x);
printf("输入特殊方格的横坐标:
");
scanf_s("%d",&y);
ChessBoard(0,0,x,y,size);
printf("程序运行结果如下所示:
\n");
for(inti=0;ifor(intj=0;jprintf("%d\t",Board[i][j]);
}
printf("\n");
}
printf("\n");
system("pause");
}
运行结果
经验归纳
结合书上核心代码,理解起来还是有些吃力。
实验总结
本次实验较上次难,也是一个循序渐进的过程,认真学习,受益匪浅。
展开阅读全文
相关搜索