数据结构课程设计奇偶魔方阵.docx
- 文档编号:7828706
- 上传时间:2023-01-26
- 格式:DOCX
- 页数:18
- 大小:64.78KB
数据结构课程设计奇偶魔方阵.docx
《数据结构课程设计奇偶魔方阵.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计奇偶魔方阵.docx(18页珍藏版)》请在冰豆网上搜索。
数据结构课程设计奇偶魔方阵
1引言
本课程设计主要解决一个古老的智力问题。
它要求在一个n*n矩阵中填入1到n*n数字(由于只是奇数的话,过于简单,因此,我不限定n),使得每一行、每一列、每条对角线的累加和都相等。
输入x,要求打印由自然数1到n*n构成的魔方阵。
1.1课程设计目的
本课程设计是建立在数据结构这门课程基础上,数据结构是计算机及相关专业基础课,也是计算机及相关专业考研和水平等级考试的必考科目。
它所讨论的知识内容和提倡的技术方法,无论对进一步学习计算机领域的其他课程,还是对从事软件工程的开发,
都有着不可代替的作用。
为了适应21世纪人才培养的需要,理论知识与实践训练相结合,培养动手能力,是课程设计的最终目的,通过实际项目的分析、设计、编码、测试等工作,掌握用C++语言来开发和维护软件;按要求编写课程设计报告书,能正确编写分析、设计、编码、测试等技术文档。
1.2课程设计内容
就本课程设计而言,程序设计的结构是为了体现数据结构的思想与内容,在正文第二节设计思路与方案中算法设计的描述,通过自然语言来详尽地梗概魔方阵的实现过程,同时,会在第三节中用程序设计语言(C++语言)[1][2][3]书写的算法语句和解释来详细描述魔方阵实现进程,算法描述后是运行环境与运行结果,通过调试来完善算法,达到最终要求。
最后是本人的结束语,其中有本课程设计的技术总结,并附带参考文献与程序设计的源代码,便于读者查看。
2设计思路与方案
。
2.1设计思路
(1)当n为奇数时,即n=2*m+1时,算法为:
首先,把1填在第一行的正中间。
其次,若数k填在第i行第j列的格子中,那么k+1应填在它的左上方,即i-1,j-1;如果左上方没有格子,若i-1=0,那么k+1填在第n行第j-1列的格子中;若j-1=0,那么k+1填在第i-1行第n列的格子中;若i-1=0,j-1=0,那么k+1填在第n行第n列的格子中。
再次,若按上述方法找到的格子都已经填过了数,那么,数k+1填在第k个数的正下方。
具体实现时:
用i<0,j<0表明格子不存在。
找到的格子都已经填过了数的这类数有个特点,那就是可以整除n,即k%n=0。
(2)当n为双偶数时,即n=2*2*m时,算法为:
将所要求的魔方阵分为上下左右4个n/2*n/2的小方阵。
首先,在左上角的方阵中做记号,每行每列,各取一半打上记号。
然后,将其向其余3个方阵中映像。
接着,从左上角格子开始,按从左到右,从上到下的次序将1到n*n的值往方阵中填写,但遇到作了标记的格子时跳过。
再从右下角格子开始,按从右到左,从下到上的次序将1到n*n的值往方阵中填写,但遇到已填过值的格子时跳过,既可以构成一个魔方阵。
具体实现时:
左上角和右下角的n/2*n/2的小矩阵,偶行偶列,奇行奇列赋值为0,其余赋值为1;右上角和左上角的n/2*n/2的小矩阵,偶行奇列,奇行偶列赋值为0,其余赋值为1。
然后,从左上角格子开始,按从左到右,从上到下的次序将1到n*n的值往方阵中赋,但遇到值为0时跳过;再从右下角格子开始,按从右到左,从下到上的次序将1到n*n的值往方阵中赋,但遇到值为1时跳过。
(3)当n为单偶数时,即n=2*(2*m+1)时,算法为:
把n阶模仿阵先均分为A,B,C,D四个同样的小方阵,先按先前奇数阶魔方的形成方法在A,B,C,D中构成四个奇阶魔方,其中,A用1到n/2*n/2填写;B用n/2*n/2+1到2*n/2*n/2填写;C用2*n/2*n/2+1到3*n/2*n/2填写;D用3*n/2*n/2+1到n*n填写。
先在A的中间一行从左侧的第二列起取m个格子,把这些格子中的数字同D相应格子中的数字对调;然后,在C中从最后一列起在各行中取m-1个格子,把这些格子中的数字同B相应格子中的数字对调。
具体实现时:
设A,B,C,D四个二维数组,对于A调用形成奇阶魔方的函数array_pointerjishu(intn,intmatrix1[][100]),将A用1到n/2*n/2排成魔方阵。
B,C,D魔方阵有个特点就是分别在前一个魔方阵中各个数字上加n/2*n/2所构成的新魔方阵,则设了一个实现此功能的函数array_pointerfirst(intn,intA2[][100],intB2[][100])。
然后,采用引用的方法设了一个实现相应位置上函数交换的函数voidswap(int&w,int&v)。
最后,将四个小方阵联结起来构成所要求的魔方阵。
2.2设计方案
应把n分为三类,这三类n构成的魔方阵的算法各不相同,如同思路中介绍的那样分别进行描述。
在实现上述过程之前,由于数组的局限性,首先设了一个大数组intmatrix[100][100],若n大于100,只能进一步扩大数组。
二维数组作为参数在调用函数与被调用函数之间传递,与一位数组的传值不同。
我通过查看C++语法书[1]找到了利用typedef实现从多位数组返回地址的方法,。
但当被调函数再调用函数时,却无法用typedef实现二维数组值的再传递,因此,只能在被调函数中直接实现,故程序中有些语句重复冗长。
3设计的详细实现
打开程序操作平台VisualC++6.0,新建基于Win32ConsoleApplication空工程作为工作区间,并添加file魔方阵.cpp;#include
.
typedefint(*array_pointer)[100];
//typedef语句创建名称array_pointe作为一个指向int型的长度为100的一维数组的指针的别名
·N为奇数时算法的实现:
array_pointerjishu(intn,intmatrix1[][100])
//当n为奇数时,即n=2m+1,实现奇数阶魔方的函数
(在for结构中实现)matrix1[i][j]=k;//将k放在k-1的左上角;if(k%n==0)//若k-1左上角已经有数了,则k填在k-1正下方,而此时k有个特点就是可以被n整除;else
{
if(i<0)//k-1左上角的格子若不存在的解决办法
i+=n;//若行不存在,则行变为n行
if(j<0)//若列不存在,则列变为n列
j+=n;
·N为双偶数时算法实现:
array_pointershuangoushu(intn,intmatrix3[][100])
//当n为双偶数时,即n=2*2m,实现双偶数阶魔方的函数
for(i=0;i //首先,对魔方数组进行赋值,达到标记的目的将魔方阵分为四个部分: 左上角,右上角,左下角,右下角.分别进行赋值 for(j=0;j {...............} //赋值的原则为: 左上角的n/2*n/2的小矩阵,偶行偶列,奇行奇列赋值为0,其余赋值为1 for(j=n/2;j {................}. //右上角的n/2*n/2的小矩阵,偶行奇列,奇行偶列赋值为0,其余赋值为1 for(i=n/2;i { for(j=0;j .{.............} //左下角的n/2*n/2的小矩阵,偶行奇列,奇行偶列赋值为0,其余赋值为1 for(j=n/2;j {................} //右下角的n/2*n/2的小矩阵,偶行偶列,奇行奇列赋值为0,其余赋值为1 for(i=0;i {...............} //从左上角格子开始,按从左到右,从上到下的次序将1到n*n的值往方阵中填写,但遇到值为0时跳过 for(i=n-1;i>=0;i--) {.............} //从右下角格子开始,按从右到左,从下到上的次序将1到n*n的值往方阵中填写,但遇到值为1时跳过 array_pointerfirst(intn,intA2[][100],intB2[][100]) {.........} //当n为双偶数时,对B,C,D进行赋值的函数 voidswap(int&w,int&v) {..........} //交换对应位置数组值的函数 ·N为单偶数时算法设计: array_pointerdanoushu(intn,intmatrix1[][100]) {...................} //当n为单偶数时,即n=2*(2m+1),实现单偶数阶魔方的函数 其中,将魔方阵数组划分为四个n/2*n/2的奇阶数组方阵: A,B,C,D。 并分别进行声明 int(*A1)[100];//A1为一个指向int型的长度为100的一维数组的指针 ...........依次声明B1、C1、D1 A1=jishu(n/2,A); //调用实现奇数阶魔方的函数jishu,将1到n/2*n/2填入A1中行成一个奇阶魔方阵 B1=first(n,A1,B); //调用赋值的函数first,将n/2*n/2+1到2*n/2*n/2填入中行成一个奇阶魔方阵 C1=first(n,B1,C); //调用赋值的函数first,将2*n/2*n/2+1到3*n/2*n/2填入中行成一个奇阶魔方阵 D1=first(n,C1,D); //调用赋值的函数first,将3*n/2*n/2+1到n*n填入中行成一个奇阶魔方阵 for(i=0;i { for(j=n/2-1;j>n/4;j--)//1到n/4行,n/2-1到n/4列,交换A1与D1相应位置的值,通过调用交换函数swap swap(A1[i][j],D1[i][j]); } for(j=n/2-2;j>n/4-1;j--)//n/4行,n/2-2到n/4-1列,通过调用交换函数swap,交换A1与D1相应位置的值 swap(A1[n/4][j],D1[n/4][j]); for(i=n/4+1;i { for(j=n/2-1;j>n/4;j--) swap(A1[i][j],D1[i][j]); } for(i=0;i { for(j=0;j swap(B1[i][j],C1[i][j]); } for(i=0;i {.............} //将四个数组A1,B1,C1,D1连起来构成魔方阵matrix1 函数返回魔方阵数组matrixl ·打印函数算法实现: array_pointerprint(intn,intmatrix1[][100])//打印函数,打印出魔方阵 { inti,j; for(i=0;i { for(j=0;j { cout< } cout< } returnmatrix1; } ·主函数算法实现: voidmain()//主函数 { intn; cout<<"魔方阵"< n="; cin>>n; if(n<=2) { cout<<"输出矩阵不为魔方阵"< } intmatrix[100][100];//声明一个魔方阵二维数组matrix int(*matrix2)[100]; //matrix2为一个指向int型的长度为100的一维数组的指针 if(n%2==1)//当n为奇数时,调用实现奇数阶魔方的函数 matrix2=jishu(n,matrix); else { if(n%4==0)//当n为双偶数时,调用实现双偶数阶魔方的函数 matrix2=shuangoushu(n,matrix); else matrix2=danoushu(n,matrix); //当n为单偶数时,调用实现单偶数阶魔方的函数 } print(n,matrix2);//调用打印函数,打印出魔方阵 } 4调试与运行 调试结果如图4.1所示: 图4.1调试结果图 //************************************************************************// 组建如图4.2所示: 图4.2组建图 //************************************************************************// ·初步运行出现窗口如图4.3所示: 图4.3初步运行图 ·近一步运行,如果输入错误数据2,然后会提示输出矩阵不为魔方阵 结果如图4.4所示: 图4.4输入错误图 ·当输入奇数时结果正确,奇数阶魔方阵实现 结果如图4.5所示: 图4.5奇数阶魔方图 ·当输入单偶数时,输出结果正确,单偶数魔方阵实现 结果如图4.6所示: 图4.6单偶数阶魔方图 ·当输入双偶数时,输出结果正确,双偶数魔方阵实现 结果如图4.7所示: 图4.7双偶数阶魔方图 程序运行时首先提示输入的值,确定即可输出魔方阵。 但须注意n的值大于等于3的,当输入1或2时,也有输出但不为魔方阵。 由进一步改进,将其中部分重复语句改成调用函数,但首先得解决二维数组的传值问题。 由以上多种测试调试结果显示,程序设计已可以实现奇偶数阶魔方阵。 5结束语 在本课程设计中主要用到广义线性表----多维数组和广义表,线性表是由n个具有相同类型数据元素组成的有限序列。 广义表是n个数据元素的有限序列,n可以是单个数据元素,也可以是一个广义表,广义表中元素具有递归性,广义表可以是其自身的子表,并且元素可共享,当二维数组的每行或每列作为子表处理时,二维数组即为一个广义表。 在编程过程中学习了很多,巩固了很多C++语言程序设计和数据结构的知识,同时在参考资料书与网络资源时,也扩展了自己在C++语言与数据结构方面的知识面,并且在学习和交流的过程中,思考很多,学到很多,更加认识到自己在计算机领域中是多么渺小,和同行业的网友交流中,认识到学无止尽,到大学三年纪了,留给我们的时间已经不多,只会编写一些简单的程序是远远不够的,学习的过程是艰难的,但有了同学、朋友、老师的陪伴,我不会气馁。 在此我要多谢陈倩诒老师的指导,和舍友的帮助,为了以后更好的学习数据结构,请老师您抽出宝贵的时间来给予意见反馈,以便我更好地改进本课程设计。 . 参考文献 [1]StanleyB.Lippman,JoseeLajoieandBarbaraE.Moo.李师贤,蒋爱军,梅晓勇,林瑛.C++Primer中文版.人民邮电出版社.北京.2008 [2]H.M.DeitelandP.J.Deitel.荣耀.C++程序设计.人民出版社,2005.110~123 [3]HerbSutterandAndreiAlexandrescu.刘基诚.C++编程规范.2005.258~263 [4]郑阿奇,丁有和.VisualC++教程.机械工业出版社.2007.89~117 [5]教程内容,容易理解魔方阵源程序,中科软件园 附录 源程序: //程序名称: 魔方阵.CPP //程序功能: 把整数1到n*n排列成一个n*n方阵,使方阵中的每一行,每一列以及对角线上的数之和都相同。 //程序作者: //最后修改日期: 2009-09-19 #include #include typedefint(*array_pointer)[100]; //typedef语句创建名称array_pointer作为一个指向int型的长度为100的一维数组的指针的别名 array_pointerjishu(intn,intmatrix1[][100]; //当n为奇数时,即n=2m+1,实现奇数阶魔方的函数 { inti,j,k; i=0;//将1放在第一行第一例 j=n/2; for(k=1;k<=n*n;k++) { matrix1[i][j]=k;//将k放在k-1的左上角 i--; j--; if(k%n==0)//若k-1左上角已经有数了,则k填在k-1正下方,而此时k有个特点就是可以被n整除 { i+=2; j++; } else { if(i<0)//k-1左上角的格子若不存在的解决办法 i+=n;//若行不存在,则行变为n行 if(j<0)//若列不存在,则列变为n列 j+=n; } } returnmatrix1;//返回魔方阵数组 } array_pointershuangoushu(intn,intmatrix3[][100])//当n为双偶数时,即n=2*2m,实现双偶数阶魔方的函数 { inti,j; for(i=0;i 将魔方阵分为四个部分: 左上角,右上角,左下角,右下角.分别进行赋值*/ { for(j=0;j 左上角的n/2*n/2的小矩阵,偶行偶列,奇行奇列赋值为0,其余赋值为1 { if(i%2==0) { if(j%2==0) matrix3[i][j]=0; else matrix3[i][j]=1; } else { if(j%2==1) matrix3[i][j]=0; else matrix3[i][j]=1; } } for(j=n/2;j { if(i%2==0) { if(j%2==1) matrix3[i][j]=0; else matrix3[i][j]=1; } else { if(j%2==0) matrix3[i][j]=0; else matrix3[i][j]=1; } } } for(i=n/2;i { for(j=0;j { if(i%2==0) { if(j%2==1) matrix3[i][j]=0; else matrix3[i][j]=1; } else { if(j%2==0) matrix3[i][j]=0; else matrix3[i][j]=1; } } for(j=n/2;j { if(i%2==0) { if(j%2==0) matrix3[i][j]=0; else matrix3[i][j]=1; } else { if(j%2==1) matrix3[i][j]=0; else matrix3[i][j]=1; } } } for(i=0;i { for(j=0;j { if(matrix3[i][j]==1) matrix3[i][j]=i*n+j+1; } } for(i=n-1;i>=0;i--)//从右下角格子开始,按从右到左,从下到上的次序将1到n*n的值往方阵中填写,但遇到值为1时跳过 { for(j=n-1;j>=0;j--) { if(matrix3[i][j]==0) matrix3[i][j]=(n-1-i)*n+(n-1-j)+1; } } returnmatrix3; } array_pointerfirst(intn,intA2[][100],intB2[][100])//当n为双偶数时,对B,C,D进行赋值的函数 { inti,j; for(i=0;i { for(j=0;j B2[i][j]=A2[i][j]+(n/2)*(n/2); } returnB2; } voidswap(int&w,int&v)//交换对应位置数组值的函数 { inttemp; temp=w; w=v; v=temp; } array_pointerdanoushu(intn,intmatrix1[][100])//当n为单偶数时,即n=2*(2m+1),实现单偶数阶魔方的函数 { intA[100][100];//将魔方阵数组划分为四个n/2*n/2的奇阶数组方阵: A,B,C,D。 并分别进行声明。 intB[100][100]; intC[100][100]; intD[100][100]; inti,j; int(*A1)[100];//A1为一个指向int型的长度为100的一维数组的指针 int(*B1)[100];//B1为一个指向int型的长度为100的一维数组的指针 int(*C1)[100];//C1为一个指向int型的长度为100的一维数组的指针 int(*D1)[100];//D1为一个指向int型的长度为100的一维数组的指针 A1=jishu(n/2,A);//调用实现奇数阶魔方的函数jishu,将1到n/2*n/2填入A1中行成一个奇阶魔方阵 B1=first(n,A1,B);//调用赋值的函数first,将n/2*n/2+1到2*n/2*n/2填入中行成一个奇阶魔方阵 C1=first(n,B1,C);//调用赋值的函数fi
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 课程设计 奇偶 魔方