马踏棋盘——一个数据结构综合实验案例新解
- 格式:pdf
- 大小:283.78 KB
- 文档页数:4
总第14卷157期 2012年9月 大众科技 Popular Science&Technology VoL.14 N0.9 September 201 2
马踏棋盘 一个数据结构综合实验案例新解
宁黎华 陈光喜
(1.桂林电子科技大学数学与计算科学学院,广西桂林541004;
2.桂林电子科技大学现代教育技术中心,广西桂林541004)
【摘要】首先把马踏棋盘问题作为一个综合设计案例引入到数据结构实验中,提出了用图论模型求解该问题的一个新思
路。通过对该问题进行分析,循序渐进地给出了如何利用已学知识来求解该问题的过程。最后对该案例的设计进行了总结和思 考。
【关键词】马踏棋盘;综合设计;图论
【中图分类号】TP311 【文献标识码】A 【文章编号】1008一l151(2012)09—0010—04
A new method for Horse travelling on chessboardman integrated—design case
in data structure experiment teaching
Abstract:In this paper,the problem of horse traveling on chessboard was introduced into data structure experiment teaching as an integrated—design case firstly and a new idea of using graph theory model for solving the problem was proposed.Then through the
analysis of the problem,the process how to use already learned knowledge to solve the problem was shown step by step.Finally a
summary of and a further thinking about the case design were given.
Key words:horse traveling chessboard;integrated—design;graph theory
数据结构在计算机学科中有着重要的地位,起着承上启
下的作用。通过对数据结构的学习可以锻炼学生的逻辑思维
能力,提出问题、分析问题和解决问题的能力,为学好后继
课程打下坚实的基础 。然而,数据结构也是一门理论性很强 的课程,理论知识抽象、概念多、算法多而杂,学生不好理
解,设计程序无从下手。很多学生反映这门课“难懂、不好
用”。学生不通过实践很难对其理论有深入理解和应用。因 此高质量地开设数据结构实验课十分必要,通过实验课,学
生可以把课本上看不懂的算法一步步运行出来增强理解或者
对算法的运行结果进行验证,也可以把抽象地理论应用到解 决实际问题上。
数据结构实验课的重要性目益突出,目前笔者所在的学
校已经将数据结构实验课作为一门单独的课程进行开设。而
综合实验通常是实验课设置的一个压轴环节,根据综合实验 的定义,综合性实验要求学生能够综合利用所学到的知识点,
解决一个给定的实际问题。其目的是培养学生解决问题的系 统思维能力和综合动手能力。设计适合学生、难易得当、繁
简相宜的案例,应包含学生已经学到的知识,以此为驱动进
行课程的教学和学习,提高学生的学习兴趣 。案例过大,学 生工作量大,在给定的时间完不成实验;案例太难,学生不 知从何下手,产生畏难心理,会打击学生解决问题的自信心;
而案例过于简单,则达不到综合实验要求,起不到锻炼学生 的目的。一个合适的综合实验案例,应该具有以下几个特点:
1)创新性。求解过程中包含了一种新型的求解思路;2)综 合性。内容具有代表性,涵盖多章的重要知识点 ,能够把
学生已学的各个知识点综合起来;3)可达性。难度不大,学 生容易下手,容易通过对已学理论举一反三,进行求解。
传统的马踏棋盘问题采用的回溯法或者贪心法求解 , 学生学完了数据结构课程,用此类方法求解仍具有一定难度。
就其原因,学生对数据结构的理论知识不能灵活运用以及相
关算法不熟悉,感觉这些求解算法与自己所学相差甚远。学 生关心的问题是:“学习数据结构有什么用?能否用学到的
最简单、最本质的知识点来求解给定问题?”。针对这个问 题,笔者把马踏棋盘问题作为一个综合设计案例引入到数据
结构实验中,提出了用图论模型求解该问题的一个新思路。
通过对该问题进行分析,循序渐进地引导学生如何利用已学
知识来求解该问题。最后对该案例的设计进行了总结和思考。
【收稿日期】2012—07—13 【基金项目】广西高等教育教改工程项目(2012JGA144) 【作者简介】宁黎华,女,桂林电子科技大学数学与计算科学学院讲师,研究方向为进化计算、智能算法、OBDD等;陈光
喜,男,桂林电子科技大学现代教育技术中心教授,研究方向为智能软件与算法、信息安全、符号计算。
.
10. 1马踏棋盘问题描述及求解
国际象棋的棋盘为8*8的方格棋盘。将 马 放在任意指定
的方格中,按照 马 走棋的规则将 马 进行移动。要求每个 方格只能进入一次,最终使得 马 走遍棋盘的64个方格。求
出马从给定位置出发的一条或多条路径。
图论是数据结构课程的一个重点内容,建立图的邻接表
表示及对图进行深度优先这两个算法学生已经很熟悉,如果 能用这两个熟悉的算法稍加修改来得到新算法,那马踏棋盘
问题就能迎刃而解了。
图l 国际象棋棋盘示意图
1.1建立图论模型 首先我们先来给这个问题进行建模。图1所示的是一个 8*8的国际象棋棋盘。忽略掉棋盘上的格子的颜色,该棋盘共
由64个相同的格子组成。马在棋盘上行走的规则是:先在水
平或者垂直方向上移动一格,然后再斜走一格,合起来为一 步棋。假设马当前位置,如图所示,下一步马的位置最多有8
个位置可选。马从当前格子跳到下一个格子,我们就认为当
前格子到下一个格子是可达的、有路径的,如果把每个格子 看作图中的一个顶点的话,那么当前格子和周围的八个格子
就存在着有向边关系。确定了有向图的顶点和边,有向图模 型就建好了。
为了处理方便,我们把图1所示的棋盘放在一个直接坐标
系中,取每个格子(顶点)左下角的坐标作为整个格子的坐 标。如图2所示。设马当前位置坐标为(i,j),则下一步马的
可能位置与当前位置在x、Y轴方向上的偏移量是一个固定值,
按逆时针方向分别为(2,1)、(1,2)、(一1,2)、(一2, 1)、(一2,一1)、(一1,一2)、(1,一2)、(2,一1)。有
时候如果马的位置靠近棋盘边界,那么下一步的可能的位置 就有可能越界,为了保证下一步的位置是可行的,必须限定
其x、Y坐标同时在[0,7]内。否则该位置越界了,不可取。
举个例子,假设马当前的位置为(1,1),则下一步的8个位
置的坐标分别计算得出(3,2)、(1,3)、(0,3)、(一l, 2)、 (一1,0)、 (0,一1)、 (2,一1)、 (3,0)。其中
(一1,2)、(一1,0)、(0,一1)、(2,一1)越界了,要 舍去。所以马的下一步可能位置数为4个。通过这个方法,我
们可以求出图中每个顶点的邻接点。 56.. 63一 (7。7j }}2’ ● ● 《_+ 2 k ● ● li ̄2 |+1 li, 11 @ { ・l} ● } ● +: l
l6. 一 I}2 ● ● l-+ 矗2 & 15+ (7。1J一 m 2 3一 7 啭子 一
图2直角坐标系下的棋盘位置示意图
(1)有向图的邻接表形式说明
有向图的表示有两种方式:邻接矩阵表示法和邻接表表
示法。已知图中顶点和各个顶点的邻接点,采用邻接表表示
很容易。因为计算邻接点的时候要用到顶点的坐标,所以我 们在定义表头结点的时候,不但定义了顶点的序号(vertex)
和边表头指针(1ink),还增加了一个表示顶点坐标的属性
(X,Y)。顶点序号和坐标的取值方式可见图2,不难发现, 顶点序号k与其坐标(i,j)存在以下对应关系:k-8j+i。
表头结点的结构体定义如下: Typedef struct {int vertex: 羔 :i 羔 ; edgenode 1 ink: ) 边结点的定义如下:
Typedef struct node
{int adjvex: struet node*next
}edgenode: 其中next为链域指针,在邻接表中指向下一个边结点。 接下来要建立图的邻接表表示算法了。
(2)邻接表建立算法
算法2.1给出了从给定的图建立其邻接表的算法的步骤 及c语言描述 :
算法2.1
1)读入顶点信息,初始化表头结点顶点域;表头结点初 始化为空;
For(i=O:i<n:i++) {ga[i].vertex=getchar 0:
ga[i].1ink=NULL;)
2)读入图中e条边,每读入一条边<i,j>,将序号为j的结
点作为邻接点链在表头结点i的边表中,并且是以头插法的方
式链入。 For(k=0:k<e:k++)
{scanf(“%d%d”,&i,&j): s=malloc(sizeof(edgenode)):
s一>adjvex=j: s一>next=ga[i].1ink:
对上述算法2.1略加以下两处改动,我们可建立棋盘的图
的邻接表表示算法2.2。
改动i:图中的项点序号及坐标不是从给定图读入的,而 是我们事先按照某个次序(如图2所示的次序)确定好的。为
方便起见,我们取顶点序号为表头结点在邻接表中的下标。
改动2:算法2.1中是通过读入给定图中的边来确定顶点 和顶点之间的邻接关系。而算法2.2中,给定任何一个顶点,
我们是通过周围8个邻接点的相对位移算出它的邻接点。 算法2.2
i)读入顶点信息,初始化表头结点坐标域、顶点域:表
头结点初始化为空。 for(i=O:i<n:i++)
for(j=o:j<n:j++)
{g[n*i+j].x=j: g[n*i+j].y=i:
g[n*i+j].vex=n*i+j:
g[n*i+j].1ink=NULL:j 2)从表头结点第一个节点开始,据其坐标算出其邻接点 的坐标,继而推导出邻接点序号,若邻接点满足条件,则将
该结点作为邻接点链在相应表头结点边表中,并且是以头插 法的方式链入。 for(k=O:k<n*n:k++) {for(i=O:i<8:i十十) if(<g[k].x+px[i],g[k].y+py[i]>满足要求没有越界) (动态生成结点S s一>vex=n*(g[k].y+py[i]) g[k].x+px[i]: s一>next=g[k].1ink: g[k].1ink=s:}} 至此,邻接表已经建立,接下来我们讨论图的遍历问题。 1.2图的遍历 图的模型建好以后,马踏棋盘问题就转化成求马遍历图
中各个顶点一次且仅一次的一条或多条路径的问题。8 X 8的
棋盘构成了一个具有64个顶点的连通图,对这个连通图进行