数据结构课程设计--修道士野人问题和西文图书管理系统

合集下载
相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

题号题目3、修道士与野人问题

1、需求分析

n个修道士和n个野人渡河,只有一条小船,能容纳c人,两种人都会划船,建立过河方式。满足:

野人无法侵犯修道士。这就要求无论在何处,修道士的个数不得少于野人的人数(除非修道士个数为0)。设计程序模拟该过程。

程序的输入为修道士(野人)的个数以及每条船容纳人的个数。输出为判断是否可以安全渡河。如果能,则给出一个小船来回次数最少的最佳方案。

要求:

(1)用一个三元组(x1,x2,x3)表示渡河过程中各个状态。其中,x1表示起始岸上修道士个数,x2表示起始岸上野人个数,x3表示小船位置(0——在目的岸,1——在起始岸)。例如(5,3,0)表示起始岸上有5个修道士,3个野人,小船在目的岸一边。

(2)采用邻接表做为存储结构。最短路径搜索采用广度搜索法。

(3)输出最优解

若问题有解(能渡过河去),则输出一个最佳方案。用三元组表示渡河过程中的状态,并用箭头指出这些状态之间的迁移:

目的状态←…中间状态←…初始状态。

若问题无解,则给出“渡河失败”的信息。

(4)求出所有的解。

2、设计

2.1设计思想

(1)数据结构设计:根据题目要求,用图形结构,用邻接表来存储结点,以及结点之间的关系,同时在广度优先遍历中利用到队列。

(2)算法设计:先定义一个图利用邻接表储存结构,再举出在船上修道士和野人的所有情况,然后判断其修道士是否处于安全的状态,如果安全则将该点添加到图中,点添加完后在看两点之间是否连通如果连通则可将边添加到图中,这样就创建出了图,然后分别利用广度搜索和深度搜索来完成题目的要求。

2.2

(1

(2)函数接口规则说明

int Search(AdjLGraph *G,int x,int y,int m ) /*查找起始和最后的结点,其中x,y,m分别表示起始岸修道士人数,野人人数和船的状态*/

int Checking(DataType x) /*检查修道士是否安全,x表示邻接表中的一个结点*/

int Connect(AdjLGraph *G,int i,int j) /*将能走通的点连接起来,i,j为图中的两个结点*/ void Creat(AdjLGraph *G) /*图的创建*/

int Print(AdjLGraph G) /*从后向前打印最短路径*/

int BroadFSearch(AdjLGraph G,int u,int v) /*用广度优先遍历搜索最短路径,u表示起始结点,v表示最后的结点*/

void Print1(AdjLGraph G) /*打印输出所有最短路径*/

void DFS(AdjLGraph G,int u,int v ,int visited[]) /*利用深度搜索找出所有最短路径,u表示起始结点,v表示最后的结点,visited[]用来标记结点是否被访问*/

2.3详细设计

首先是定义邻接表

typedef struct

{

int daoshi; //道士

int yeren; //野人

int ship; //船的位置

}DataType;

typedef struct Node //边结点的结构体

{

int dest; //邻接边的弧头顶点序号

struct Node *next; //单链表的下一个结点指针

}Edge;

typedef struct

{

DataType data; //顶点数据元素

int source; //弧尾顶点序号

Edge *adj; //邻接边的头指针

}AdjLHeight;

typedef struct

{

AdjLHeight a[200]; //邻接表数组

int numOfVerts; //顶点个数

int numOfEdges; //边个数

}AdjLGraph; //邻接表结构体

同时定义了几个全局变量,便于函数的直接利用

int n,c;//修道士和野人人数为n,船能容纳人数为c

int Path[200]; //保存结点的后驱结点

int Path1[200]; //保存结点的前驱结点

利用上述结构和相关函数可以构造出图,然后对图进行利用;

然后在广度优先遍历搜索中用到了队列

typedef struct

{

int queue[200];

int rear;

int front;

int count;

}SeqCQueue;

最后通过主函数main调用各函数得到相关信息

int main()

{

AdjLGraph G;

int visited[200]; //标记结点是否被访问

printf("输入小船可装的人数:\n");

while(scanf("%d",&c)!=EOF)

{

memset(Path,0,sizeof(0));

memset(visited,0,sizeof(visited));

memset(Path1,0,sizeof(Path1));

N=0;

printf("输入野人或修道士的个数:\n");

scanf("%d",&n);

AdjInitiate(&G);

Creat(&G);

v1=Search(&G,n,n,1);

v2=Search(&G,0,0,0);

if(BroadFSearch( G,v1, v2)==0)

printf("渡河失败\n");

else{

printf("输出所有最短路径的情况:\n");

DFS(G,v1,v2,visited);

printf("共有%d种情况\n",N);

}

printf("输入小船可装的人数:\n");

}

return 0;

}

3、调试分析

在进行运行的时候,曾出现了打印输出错误,经过一步一步调试,发现在插入结点的时候出现了插入错误,即没有考虑到结点后驱的改变,通过改正,重新运行检测,运行结果正确,在排版时通过一步步调试,能够使输出结果很明显的表示的船的方案。

4、用户手册

相关文档
最新文档