简介:
实验目的:
1、了解图的应用
2、加深对图结构及算法的理解
3、培养解决实际问题的编程能力
实验内容:
国际象棋马的走法:先直走或横走一格,再沿离开原来格子的方向斜走二格,合起来为一步棋;国际象棋棋盘黑白交错,格数8×8。
基本要求:
给出马从任意一个位置出发遍历整个棋盘的一条路径。
在1)的基础上给出从该位置出发的所有遍历路径
马踏棋盘
任务一:
问题建模-将马踏棋盘问题用无向图建模,输出图的邻接表表示
任务描述:
本关任务:将棋盘转换成图的邻接表表示模型,并输出邻接表。
相关知识:
为了完成本关任务,你需要掌握:
1.问题建模
2.如何输出邻接表
- 问题建模
整个棋盘可表示为一个N×N的二维数组。假若马目前在位置(i,j)则马下一步可移动的位置最多有八个(如上图所示八个小黑点)。这八个位置(用0、1、……、7来标示)与当前位置在x,y方向上有固定位移差。0~7号位置(x,y)可以表示为:
(i-2,j+1),(i-1,j+2),(i+1,j+2),(i+2,j+1),
(i+2,j-1),(i+1,j-2),(i-1,j-2),(i-2,j-1)。
当然,这些位置一定在棋盘边界以内,即位置坐标(x,y)必须满足:
0<=x<=N-1 &&0<=y<=N-1
如何定义邻接关系?
马当前所在格子(i,j),马的下一步最多有八个格子可以到达。我们就认为当前格子和下一步能够到达的格子是“可达的”,这种“可达性”具有对称性。如果把格子看作一个顶点的话,那一个格子最多有8个格子可达,下一步马能到达的格子就是当前格子的邻接点。一个 N * N 棋盘可以转换成一个具有 N * N 个顶点的无向图。
为了方便,格子除了具有坐标属性(以格子左下角坐标表示),我们还可以给每个格子增加一个序号属性。
以5*5棋盘为例,假定我们按照以下方式对棋盘上的格子进行编号,那么编号与格子所在的坐标位置必然存在一定关系。
(0,4) , 20 | (1,4) , 21 | (2,4) , 22 | (3,4) , 23 | (4,4) , 24 |
---|---|---|---|---|
(0,3) , 15 | (1,3) ,16 | (2,3) , 17 | (3,3) , 18 | (4,3) , 19 |
(0,2) ,10 | (1,2) , 11 | (2,2) , 12 | (3,2) , 13 | (4,2) , 14 |
(0,1) , 5 | (1,1) , 6 | (2,1) , 7 | (3,1) , 8 | (4,1) , 9 |
(0,0) , 0 | (1,0) , 1 | (2,0) , 2 | (3,0) , 3 | (4,0) , 4 |
对于每一个顶点(格子),它的邻接点都可以计算出来。
举例:以上图中6号格子为例
6号格子坐标(1,1)
根据偏移量,计算它的下一步的8个位置的坐标:
0~7号位置分别为:
(-1,2)(0,3)(2,3)(3,2)
(3,0)(2,-1) (0,-1) (-1,0)
其中:第1、5、6、7个位置越界,舍掉
因此6号格子(顶点)有4个邻接点。
既然我们能计算出每个顶点的邻接点,那我们就很容易生成图的邻接表了。
表头结点结构:
x y k link
边结点结构:
k next
其中
k:表头结点或边结点的序号
x:表头头结点所在的横坐标;
y:表头结点所在的纵坐标;
link:表头结点中指向边结点所在链表的表头结点。
next:边结点中指向后继的指针
- 邻接表的生成
- 编程要求
以N=8为例:根据提示,在右侧编辑器写出完整代码,实现邻接表的输出。
测试说明:
测试输入:无
(在程序中#define N 8)
测试输出:
(0,0),0->17 10
(1,0),1->18 16 11
(2,0),2->19 17 8 12
(3,0),3->20 18 9 13
(4,0),4->21 19 10 14
(5,0),5->22 20 11 15
(6,0),6->23 21 12
(7,0),7->22 13
(0,1),8->25 2 18
(1,1),9->26 24 3 19
(2,1),10->27 25 16 0 4 20
(3,1),11->28 26 17 1 5 21
(4,1),12->29 27 18 2 6 22
(5,1),13->30 28 19 3 7 23
(6,1),14->31 29 20 4
(7,1),15->30 21 5
(0,2),16->33 1 10 26
(1,2),17->34 32 0 2 11 27
(2,2),18->35 33 24 8 1 3 12 28
(3,2),19->36 34 25 9 2 4 13 29
(4,2),20->37 35 26 10 3 5 14 30
(5,2),21->38 36 27 11 4 6 15 31
(6,2),22->39 37 28 12 5 7
(7,2),23->38 29 13 6
(0,3),24->41 9 18 34
(1,3),25->42 40 8 10 19 35
(2,3),26->43 41 32 16 9 11 20 36
(3,3),27->44 42 33 17 10 12 21 37
(4,3),28->45 43 34 18 11 13 22 38
(5,3),29->46 44 35 19 12 14 23 39
(6,3),30->47 45 36 20 13 15
(7,3),31->46 37 21 14
(0,4),32->49 17 26 42
(1,4),33->50 48 16 18 27 43
(2,4),34->51 49 40 24 17 19 28 44
(3,4),35->52 50 41 25 18 20 29 45
(4,4),36->53 51 42 26 19 21 30 46
(5,4),37->54 52 43 27 20 22 31 47
(6,4),38->55 53 44 28 21 23
(7,4),39->54 45 29 22
(0,5),40->57 25 34 50
(1,5),41->58 56 24 26 35 51
(2,5),42->59 57 48 32 25 27 36 52
(3,5),43->60 58 49 33 26 28 37 53
(4,5),44->61 59 50 34 27 29 38 54
(5,5),45->62 60 51 35 28 30 39 55
(6,5),46->63 61 52 36 29 31
(7,5),47->62 53 37 30
(0,6),48->33 42 58
(1,6),49->32 34 43 59
(2,6),50->56 40 33 35 44 60
(3,6),51->57 41 34 36 45 61
(4,6),52->58 42 35 37 46 62
(5,6),53->59 43 36 38 47 63
(6,6),54->60 44 37 39
(7,6),55->61 45 38
(0,7),56->41 50
(1,7),57->40 42 51
(2,7),58->48 41 43 52
(3,7),59->49 42 44 53
(4,7),60->50 43 45 54
(5,7),61->51 44 46 55
(6,7),62->52 45 47
(7,7),63->53 46
- 示例代码如下:(温馨提示:本文全部代码只在 EduCoder 平台上通过测试,仅供参考,如有运行错误请自行改正)
#include<stdio.h>
#include<stdlib.h>
#define N 8
typedef struct node
{
int k;
struct node *next;
}edgenode;
typedef struct
{
int x,y;
int k;
edgenode *link;
}vexnode;
vexnode ga[N*N];
int PX[8]={2,2,1,-1,-2,-2,-1,1};
int PY[8]={1,-1,-2,-2,-1,1,2,2};
void creatadjlist(vexnode ga[]) //创建邻接表
{
int i,j,k;
int xx,yy,newx,newy,newk;
edgenode *s;
edgenode *p;
for(j=0;j<N;j++)
for(i=0;i<N;i++)
{
k=N*j+i;
ga[k].x=i;
ga[k].y=j;
ga[k].k=k;
ga[k].link=NULL;
}
for(i=0;i<N*N;i++)
{
xx=ga[i].x;
yy=ga[i].y;
for(j=0;j<8;j++)
{
newx=xx+PX[j];
newy=yy+PY[j];
if(newx>=0 && newx<N && newy>=0 && newy<N) //头插法
{
newk=N*newy+newx;
s=(edgenode *)malloc(sizeof(edgenode));
s->k=newk;
s->next=ga[i].link;
ga[i].link=s;
}
}
}
for(i=0;i<N*N;i++)
{
printf("(%d,%d),%d->",ga[i].x,ga[i].y,ga[i].k);
p=ga[i].link;
while(p)
{
printf("%d ",p->k);
p=p->next;
}
printf("\n");
}
}
int main()
{
creatadjlist(ga);
return 0;
}
任务二:
遍历算法的实现
任务描述:
给出马从任意一个位置出发遍历整个棋盘的一条路径。
- 示例代码如下:(温馨提示:本文全部代码只在 EduCoder 平台上通过测试,仅供参考,如有运行错误请自行改正)
#include<stdio.h>
#include<stdlib.h>
#define N 6
typedef struct node
{
int k;
struct node *next;
}edgenode;
typedef struct
{
int x,y;
int k;
edgenode *link;
}vexnode;
typedef struct
{
edgenode *data[MAXSIZE];
int top;
}stack s;
stack s;
void push(stack *s,edgenode *x)
{if (s->top == MAXSIZE-1)
printf("overflow!");
s->top++;
s->data[s->top]=x;
}
edgenode* pop(stack *s)
{
if(s->top==-1)
{
printf("overflow!"); return NULL;
}
return s->data[s->top--];
}
void output(stack *s)
{
int i;
for(i=0;i<=s->top;i++)
printf("%d ",s->data[i]->k);
}
vexnode ga[N*N];
int visited[N*N]={0};
int path[N*N]={-1};
int PX[8]={2,2,1,-1,-2,-2,-1,1};
int PY[8]={1,-1,-2,-2,-1,1,2,2};
void creatadjlist(vexnode ga[])
{
int i,j,k;
int xx,yy,newx,newy,newk;
edgenode *s;
edgenode *p;
for (j=0;j<N;j++)
for (i=0;i<N;i++)
{
k=N*j+i;
ga[k].x=i;
ga[k].y=j;
ga[k].k=k;
ga[k].link=NULL;
}
for (i=0;i<N*N;i++)
{
xx=ga[i].x;
yy=ga[i].y;
for(j=0;j<8;j++)
{
newx=xx+PX[j];
newy=yy+PY[j];
if(newx>=0 && newx<N && newy>=0 && newy<N)
{
newk=N*newy+newx;
s=(edgenode *)malloc(sizeof (edgenode));
s->k=newk;
s->next=ga[i].link;
ga[i].link=s;
}
}
}
}
for (i=0;i<N*N;i++)
{
printf("(%d,%d),%d->",ga[i].x,ga[i].y,ga[i].k);
p=ga[i].link;
while(p)
{
printf("%d ",p->k);
p=p->next;
}
printf("\n");
}
}
void path_list()
{
int i;
for (i=0;i<N*N;i++)
printf("(%d,%d)" ,i,path[i]);
}
dfs(int i)
{
edgenode *p;
p=ga[i].link;
visited[i]=1;
while(s.top!=-1||p)
{
while(p)
{
if (!visited[p->k])
{visited[p->k]=1; push(&s,p);
p=ga[p->k].link;
}
else p=p->next;
}
if(s.top==N*N-2)
{
printf("succeed!");
printf("起点是0,依次经过的顶点序列:\n");
output(&s);return 1;
}
if(s.top!=-1)
{
p=pop(&s);visited[p->k]=0;
p=p->next;
}
}
return 0;
}
int main()
{
s.top=-1;
creatadjlist(ga);
dfs(0);
printf("---------------------");
return 0;
}
我把我目前写的关于数据结构 题目 的链接全部汇总整理在下面,有需要的小伙伴自己点击哈。
- 数据结构 习题 第一章 概论
- 数据结构 习题 第二章 线性表 (C语言描述)
- 数据结构 习题 第三章 栈和队列 (C语言描述)
- 数据结构 习题 第四章 串 (C语言描述)
- 数据结构 习题 第五章 多维数组和广义表(C语言描述)
- 数据结构 习题 综合复习
实验:
最近在学习最优化、运筹学和计量经济学的相关知识,实验课马上就要开了,不知道大家有没有兴趣。如果后期有时间,学习结束后,我可以整理一下上实验课的实验报告和题目,一起学习交流~