谈谈数据结构课后作业......尴尬不已...《图》 后面的迷宫问题
2016-05-28 13:48
288 查看
这个题目,要求运用广度优先搜索,然后我已开始对广搜并不太里接,到底搜的是什么?需要把图转换为邻接矩阵
吗?书上给的函数是用邻接矩阵完成的吗/?总之书上给的很复杂,有一大堆前面实现的函数,然而并不想写,太麻烦。
比如有一个搜索该点的下一个邻接点,这个函数肯定是在邻接矩阵里完成的,但是这样的话就肯定要用两个二维数组,
第一是一个用来存放01地图的数组,0代表路,1代表墙。第二个是一个邻接矩阵代表着节点之间的连通关系。这就很尴
尬了,超级复杂不是吗?书上还没给实现“搜索该点的下一个邻接点”的函数。
其实我感觉数据结构教的只是一种抽象的结构实现,并不是这个结构必须按照书上的这样实现,你只要自己完成这
个结构就好了,不管用什么方法。说到这里你可能并不理解我什么意思,假如你看懂的我下面的代码,和书上的加以比
较,再加上自己的理解,我觉得你应该能明白数据结构这本书的真正作用。
(别急先看下面的话!!)
看的时候先看主函数,再看BFS函数,再看print(注意不是printf),其实print函数不看也行。注释写的很详细了,唯一
难理解的就是那个BFS是怎么实现于队列的。你可以把队列想象成一个竖着的梯子嘛。就是第一格就是头指针,第二
格就是那个尾指针嘛,然后开始BFS,自己拿张纸画一画,在纸上画一下那个BFS的过程。
吗?书上给的函数是用邻接矩阵完成的吗/?总之书上给的很复杂,有一大堆前面实现的函数,然而并不想写,太麻烦。
比如有一个搜索该点的下一个邻接点,这个函数肯定是在邻接矩阵里完成的,但是这样的话就肯定要用两个二维数组,
第一是一个用来存放01地图的数组,0代表路,1代表墙。第二个是一个邻接矩阵代表着节点之间的连通关系。这就很尴
尬了,超级复杂不是吗?书上还没给实现“搜索该点的下一个邻接点”的函数。
其实我感觉数据结构教的只是一种抽象的结构实现,并不是这个结构必须按照书上的这样实现,你只要自己完成这
个结构就好了,不管用什么方法。说到这里你可能并不理解我什么意思,假如你看懂的我下面的代码,和书上的加以比
较,再加上自己的理解,我觉得你应该能明白数据结构这本书的真正作用。
(别急先看下面的话!!)
看的时候先看主函数,再看BFS函数,再看print(注意不是printf),其实print函数不看也行。注释写的很详细了,唯一
难理解的就是那个BFS是怎么实现于队列的。你可以把队列想象成一个竖着的梯子嘛。就是第一格就是头指针,第二
格就是那个尾指针嘛,然后开始BFS,自己拿张纸画一画,在纸上画一下那个BFS的过程。
x | y | pre | i |
4 | |||
3 | |||
.... | .... | ... | 2 |
2 | 1 | 0 | 1(rear) |
1 | 1 | -1 | 0(front) |
#include<stdio.h> int map[100][100]; //定义一个二维数组用于存放迷宫,用0,1表示 int dx[8] = {1,1,0,-1,-1,-1,0,1}; //上下为一组,8组分别表示8个方向,下 右下 右 右上... int dy[8] = {0,1,1,1,0,-1,-1,-1}; typedef struct { int x,y; //坐标 int pre; //前驱,从哪个坐标宽搜过来的 }node; node queue[100];//定义一个队列用于存放路径,用坐标表示 int print(int start)//打印路径函数,递归表示 { if(queue[start].pre != -1) //起点必为(0,0),queue[0]没有前驱,pre== -1 { map[99][99]++; //用一个不太用的点来存放步数 print(queue[start].pre); //递归,找到起点后执行下一条语句,从起点输出路径 printf("(%d,%d)\n",queue[start].x -1,queue[start].y -1);//其实并没有外面一圈墙 所以-1 } } int BFS(int a , int b , int m , int n)//最关键的广度优先搜索 { int front = 0; //头指针指向0 int rear = 1; //尾指针指向1 queue[front].x = a;//头指针指向起始位置坐标为(a,b) queue[front].y = b; queue[front].pre = -1; //起始位置没有上一个过来的位置,前驱为-1 while(front < rear) //尾指针一定在头指针上面,也可以理解为队列非空时进入循环,头尾指针相等时队列为空 { int i; for(i=0;i<8;i++) //8个方向依次搜索 { int nx = queue[front].x+dx[i]; //向下就是(a+1,b),向右就是(a,b+1) int ny = queue[front].y+dy[i]; if(map[nx][ny] == 1) continue;//如果碰到墙,不执行下面语句,继续搜其他方向 else//找到路了 { map[nx][ny] = 1; //把路变为墙,以防止再次搜索! queue[rear].x = nx; //把找到的路的坐标放进队列 queue[rear].y = ny; queue[rear].pre = front; //这个新的点是由哪个点搜过来的 rear++; //尾指针++,表示新路入队 } if(nx==m && ny==n) //如果找到了终点开始打印,并结束BFS { print(--rear); //如果上面找到了,但是rear+1了,所以这里减1进入打印函数 return 0; } } front++; //没找到的话,队头出队 } } int main() { int i,j; int m,n; scanf("%d%d",&m,&n); for(i=0;i<100;i++) for(j=0;j<100;j++) map[i][j] = 1;//初始化地图,全部置为墙 for(i=1;i<=m;i++) for(j=1;j<=n;j++) scanf("%d",&map[i][j]);//输入地图,为什么i,j从1开始?给地图周围加一圈墙,便于搜索 不出界 map[1][1] = 1;//题目要求起点为(1,1) 先把起点改为墙 printf("(0,0)\n");//先输出起点 因为输出函数到pre==-1就停止了 无法输出起点 BFS(1,1,m,n);//把起点和终点传入函数 printf("%d",--map[99][99]);//输出步数 } /* 5 5 0 1 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 0测试数据 */
相关文章推荐
- C#数据结构之顺序表(SeqList)实例详解
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#数据结构之队列(Quene)实例详解
- C#数据结构揭秘一
- C#数据结构之单链表(LinkList)实例详解
- 数据结构之Treap详解
- 用C语言举例讲解数据结构中的算法复杂度结与顺序表
- C#数据结构之堆栈(Stack)实例详解
- C#数据结构之双向链表(DbLinkList)实例详解
- JavaScript数据结构和算法之图和图算法
- Java数据结构及算法实例:冒泡排序 Bubble Sort
- Java数据结构及算法实例:插入排序 Insertion Sort
- Java数据结构及算法实例:考拉兹猜想 Collatz Conjecture
- java数据结构之java实现栈
- java数据结构之实现双向链表的示例
- Java数据结构及算法实例:选择排序 Selection Sort
- Java数据结构及算法实例:朴素字符匹配 Brute Force
- Java数据结构及算法实例:汉诺塔问题 Hanoi
- Java数据结构及算法实例:快速计算二进制数中1的个数(Fast Bit Counting)