我正在尝试使用深度优先搜索算法打印迷宫的坐标,但是,它打印出初始位置,但它会出现故障。有什么我做错了吗???这是我的代码:
#include "mazegen.h"
#include "stack.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define BUFFERSIZE 500
#define FLAG
void mazeSolution(char maze[100][100], int counter, int counter2)
{
stack*currentCell;
int i;
int j;
currentCell = create();
for(i=0; i<counter; i++)
{
for(j=0; j<counter2; j++)
{
if(maze[i][j] == 'S')
{
push(currentCell,i,j);
currentCell->visited = true;
}
}
}
printStack(currentCell);
while(currentCell != NULL)
{
pop(currentCell);
if(maze[i][j] == 'F')
{
break;
}
if(i != 0)
{
if(maze[i-1][j] == ' ' && currentCell->visited != true)
{
currentCell->visited = true;
push(currentCell,i-1,j);
}
}
if(maze[i+1][j] == ' ' && currentCell->visited != true)
{
currentCell->visited = true;
push(currentCell,i+1,j);
}
if(j != 0)
{
if(maze[i][j-1] == ' ' && currentCell->visited != true)
{
currentCell->visited = true;
push(currentCell, i,j-1);
}
}
if(maze[i][j+1] == ' ' && currentCell->visited != true)
{
currentCell->visited = true;
push(currentCell, i, j+1);
}
}
printf("No solution\n");
printStack(currentCell);
}
我认为这与我的pop功能以及我实现它的方式有关
void pop (stack*theStack)
{
node*theHead;
if(theStack == NULL)
{
printf("Empty Stack. Error\n");
exit(0);
}
theHead = removeFromFront(theStack->list);
theStack->list = theHead;
}
node*removeFromFront(node*theList)
{
node*temp;
temp = theList->next;
if(temp == NULL)
{
printf("pop Error\n");
return NULL;
}
theList = theList->next;
return theList;
}.
答案 0 :(得分:1)
查看代码的这一部分:
while(currentCell != NULL)
{
pop(currentCell);
if(maze[i][j] == 'F')
{
break;
}
...
}
您正在从堆栈中弹出一个值 - 这没关系。但您需要将弹出值分配给i
和j
。在您的代码中,i
和j
的值保持不变,因此您有一个无限while
循环。你不断在这个循环中推动堆栈中的值,最终导致段错误。
答案 1 :(得分:0)
在堆栈上保持访问状态是没用的 - 当您尝试从某个新方向访问时,您需要检查是否已访问过特定位置,如果存在循环,则可能会发生这种情况在你的迷宫中。所以这个属性的适当位置是迷宫本身,而不是堆栈。
您不需要单独的stack
和node
结构 - 堆栈实际上是节点列表。
构建堆栈非常简单,但您需要在开始编码之前想象它的结构和行为 。有两种基本(普通C)解决方案:使用预先分配的数组或动态链接列表。我们用一个数组。
堆栈的项目将是
typedef struct node {
int i, j;
} Node;
堆栈本身:
Node stack[ 10001];
目前已堆叠的一些项目:
int stkptr = 0;
现在我们可以测试堆栈是否包含任何数据:
int StackNonEmpty() { return stkptr; }
将新位置推入堆栈:
void Push(int i, int j) {
stack[ stkptr].i = i;
stack[ stkptr].j = j;
stkptr ++;
}
从堆栈的顶部读取一个位置(假设为StackNonEmpty() != 0
):
void Fetch(int *pi, int *pj) {
*pi = stack[ stkptr - 1].i;
*pj = stack[ stkptr - 1].j;
}
并将其从堆栈中删除:
void Pop() { stkptr --; }
我们还需要为访问位置定义标记:
int VISITED = '.';
或
#define VISITED '.'
我们已准备好编写算法:
for(i=0; i<counter; i++)
for(j=0; j<counter2; j++)
if(maze[i][j] == 'S')
{
Push(i,j); // set the Start position
i = counter; // this is to break the outer loop
break; // and this breaks the inner loop
}
while( StackNonEmpty())
{
Fetch(& i, & j); // get a current position
if( maze[i,j] == 'F') // Finish found?
break;
if( maze[i,j] == ' ') // empty cell?
maze[i,j] = VISITED;
// find next possible step
if( i > 0 && maze[i-1,j] == ' ') // cell to the left is empty
Push(i-1,j); // step left
else
if( j > 0 && maze[i,j-1] == ' ') // cell above is empty
Push(i,j-1); // step up
else
if( i+1 < counter && maze[i+1,j] == ' ')
Push(i+1,j); // step right
else
if( j+1 < counter2 && maze[i,j+1] == ' ')
Push(i,j+1); // step down
else // dead end - no way out
Pop(); // step back
}
if( StackNonEmpty()) // exited with break, so 'F' found
PrintStack();
else
PrintFailureMessage(); // could not reach 'F'
要显示结果,只需打印stack
数组的所有项目,直到stkptr
位置:
void PrintStack() {
for(i = 0; i < stkptr; i ++)
printf( "%d,%d\n", stack[i].i, stack[i].j);
}
修改强>
“VALID”状态分配已更正(= =而不是=),PrintFailureError
已替换为PrintFailureMessage
。