Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何在迷宫中打印从源到目标的BFS路径_C_Graph_Queue_Maze_Breadth First Search - Fatal编程技术网

C 如何在迷宫中打印从源到目标的BFS路径

C 如何在迷宫中打印从源到目标的BFS路径,c,graph,queue,maze,breadth-first-search,C,Graph,Queue,Maze,Breadth First Search,我试图实现BFS,以便在迷宫中找到从源到目标的最短路径 我遇到的问题是,我无法打印路径,它在迷宫中用“*”打印,但是如何在不打印所有访问的节点的情况下从BFS的前辈中提取路径 以下是我的代码供您编译: #include <stdio.h> #include <stdlib.h> #include <string.h> struct coord{ //This is a struct I'll use to store coordinates in

我试图实现BFS,以便在迷宫中找到从源到目标的最短路径

我遇到的问题是,我无法打印路径,它在迷宫中用“*”打印,但是如何在不打印所有访问的节点的情况下从BFS的前辈中提取路径

以下是我的代码供您编译:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct coord{   //This is a struct I'll use to store coordinates
    int row;
    int col;
};

//---------QUEUE.C-------//

struct TQueue{
    struct coord *A;
    int QUEUE_MAX;
};

typedef struct TQueue *Queue;

Queue initQueue(int size){      // Initialize the queue
    Queue Q = malloc(sizeof(struct TQueue));
    Q->A = malloc(size*sizeof(struct coord));
    Q->QUEUE_MAX = size+1;
    Q->A[0].row = 0;                //I'll use only the row value for first and last element
    Q->A[Q->QUEUE_MAX].row = 1;
    return Q;
}

int emptyQueue(Queue Q){ 
    return Q->A[0].row == 0;
}

int fullQueue(Queue Q){  
    return Q->A[0].row == Q->A[Q->QUEUE_MAX].row;
}

void enqueue(Queue Q, struct coord value){
    if(!fullQueue(Q)){
        Q->A[Q->A[Q->QUEUE_MAX].row] = value; // Insert in tail
        if(emptyQueue(Q)){
            Q->A[0].row = 1; // If is empty, the head will be in the first position
        }
        Q->A[Q->QUEUE_MAX].row = (Q->A[Q->QUEUE_MAX].row%(Q->QUEUE_MAX - 1)) + 1;
    } else{
        puts("Coda piena");
    }
}

struct coord dequeue(Queue Q){ 
    struct coord value;
    if(!emptyQueue(Q)){
        value = Q->A[Q->A[0].row];      // I take the "head" value
        Q->A[0].row = (Q->A[0].row%(Q->QUEUE_MAX - 1)) + 1;
        if(fullQueue(Q)){
            Q->A[0].row = 0;
            Q->A[Q->QUEUE_MAX].row = 1;
        }
    } else{
        puts("Coda piena");
    }
    return value;
}

//------------GRAPH.C--------

struct TGraph{
    char **nodes;
    int rows;
    int cols;
    struct coord S;
    struct coord T;
};

typedef struct TGraph *Graph;

enum color{
    WHITE, GREY, BLACK  // I will use these for undiscovered, unvisited and visited nodes
};

int BFSPathMatrix(Graph G, struct coord *pred){
    int i, j;
    struct coord neighbor, source = G->S;         //I use "source" in order to move in the maze and neighbor for visiting the adiacents
    enum color visited[G->rows][G->cols];
    for(i = 0; i < G->rows; i++)
        for(j = 0; j < G->cols; j++)
            visited[i][j] = WHITE;             //Undiscovered
    Queue coda = initQueue(G->rows*G->cols);
    visited[G->S.row][G->S.col] = GREY;               //Discovered
    enqueue(coda, source);
    i = 0;
    while(!emptyQueue(coda)){
        source = dequeue(coda);
        int moves[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};      //I can move right, left, down and up
        for(j = 0; j < 4; j++){
            neighbor.row = source.row + moves[j][0];
            neighbor.col = source.col + moves[j][1];
            if(neighbor.row < 0 || neighbor.row >= G->rows || neighbor.col < 0 || neighbor.col >= G->cols)
                continue;
            if(neighbor.row == G->T.row && neighbor.col == G->T.col){
                pred[i++] = G->T;
                //G->nodes[source.row][source.col] = '*';
                free(coda);
                return 1;
            }
            if(visited[neighbor.row][neighbor.col] == WHITE && G->nodes[neighbor.row][neighbor.col] == ' '){     //If it's undiscovered, we put it in the queue
                pred[i++] = source;
                //G->nodes[source.row][source.col] = '*';
                visited[neighbor.row][neighbor.col] = GREY;
                enqueue(coda, neighbor);
            }
        }
    }
    free(coda);
    return -1;
}

Graph initGraphMatrix(int rows, int cols){
    int i;
    Graph G = malloc(sizeof(struct TGraph));
    G->nodes = malloc(rows*sizeof(char *));
    for(i = 0; i < rows; i++)
        G->nodes[i] = malloc(cols*sizeof(char));
    G->rows = rows;
    G->cols = cols;
    return G;
}

void printGraphMatrix(Graph G){
    if(G != NULL){
        int i, j;
        for(i = 0; i < G->rows; i++){
            for(j = 0; j < G->cols; j++)
                putchar(G->nodes[i][j]);
            putchar('\n');
        }
    }
}

int main(){
    Graph G = initGraphMatrix(11, 21);
    G->S.row = 1;
    G->S.col = 1;
    G->T.row = 9;
    G->T.col = 7;
    strcpy(G->nodes[0], "|-------------------|");
    strcpy(G->nodes[1], "|S      |       |   |");
    strcpy(G->nodes[2], "| |-| |-| |---| | | |");
    strcpy(G->nodes[3], "| | |     |     | | |");
    strcpy(G->nodes[4], "| | |---| | |---| | |");
    strcpy(G->nodes[5], "| | |   | |   | | | |");
    strcpy(G->nodes[6], "| | | | |-| | | | | |");
    strcpy(G->nodes[7], "| | | |   | |     | |");
    strcpy(G->nodes[8], "| | | |-| |-------| |");
    strcpy(G->nodes[9], "|   |  T|           |");
    strcpy(G->nodes[10], "|-------------------|");
    struct coord pred[(G->rows*G->cols)];
    printGraphMatrix(G);
    system("PAUSE");
    if(BFSPathMatrix(G, pred) != -1){
        int i;
        for(i = 0; i < G->rows*G->cols; i++){
            if(pred[i].row == G->S.row && pred[i].col == G->S.col)
                continue;
            if(pred[i].row == G->T.row && pred[i].col == G->T.col)
                break;
            G->nodes[pred[i].row][pred[i].col] = '*';
        }
        printGraphMatrix(G);
    }else
        puts("Target unreachable");
    system("PAUSE");
    return 0;
}
#包括
#包括
#包括
结构坐标{//这是一个用于存储坐标的结构
int行;
int col;
};
//---------队列.C-------//
结构TQueue{
结构协调*A;
int队列_MAX;
};
typedef struct TQueue*队列;
队列初始化队列(int size){//初始化队列
队列Q=malloc(sizeof(struct TQueue));
Q->A=malloc(大小*sizeof(结构坐标));
Q->QUEUE_MAX=size+1;
Q->A[0]。行=0;//我将只对第一个和最后一个元素使用行值
Q->A[Q->QUEUE_MAX]。行=1;
返回Q;
}
int emptyQueue(队列Q){
返回Q->A[0],行==0;
}
int fullQueue(队列Q){
返回Q->A[0]。行==Q->A[Q->QUEUE_MAX]。行;
}
无效排队(队列Q,结构坐标值){
如果(!fullQueue(Q)){
Q->A[Q->A[Q->QUEUE_MAX].row]=value;//尾部插入
if(清空队列(Q)){
Q->A[0]。行=1;//如果为空,则头部将位于第一个位置
}
Q->A[Q->QUEUE_MAX]。行=(Q->A[Q->QUEUE_MAX]。行%(Q->QUEUE_MAX-1))+1;
}否则{
看跌期权(“尾声”);
}
}
结构协调出列(队列Q){
结构坐标值;
如果(!emptyQueue(Q)){
value=Q->A[Q->A[0]。行];//我取“head”值
Q->A[0]。行=(Q->A[0]。行%(Q->队列_MAX-1))+1;
if(满队列(Q)){
Q->A[0]。行=0;
Q->A[Q->QUEUE_MAX]。行=1;
}
}否则{
看跌期权(“尾声”);
}
返回值;
}
//------------图C--------
结构图{
字符**节点;
int行;
int cols;
结构协调;
结构协调;
};
typedef struct TGraph*图形;
枚举颜色{
白色、灰色、黑色//我将这些用于未发现、未访问和已访问的节点
};
int BFSPathMatrix(图G,结构坐标*pred){
int i,j;
struct coord neighbor,source=G->S;//我使用“source”在迷宫中移动,使用neighbor访问迷宫
访问的枚举颜色[G->rows][G->cols];
对于(i=0;irows;i++)
对于(j=0;jcols;j++)
访问过的[i][j]=WHITE;//未被发现
Queue coda=initQueue(G->rows*G->cols);
已访问[G->S.row][G->S.col]=灰色;//已发现
排队(尾波、震源);
i=0;
而(!emptyQueue(coda)){
来源=出列(尾波);
int moves[4][2]={{0,1},{1,0},{0,-1},{-1,0};//我可以向右、向左、向下和向上移动
对于(j=0;j<4;j++){
neighbor.row=source.row+移动[j][0];
neighbor.col=source.col+moves[j][1];
if(neighbor.row<0 | | neighbor.row>=G->rows | | neighbor.col<0 | | neighbor.col>=G->cols)
继续;
if(neighbor.row==G->T.row&&neighbor.col==G->T.col){
pred[i++]=G->T;
//G->节点[source.row][source.col]='*';
游离(尾波);
返回1;
}
如果(访问了[neighbor.row][neighbor.col]==WHITE&&G->nodes[neighbor.row][neighbor.col]==''”{//如果未发现,我们将其放入队列
pred[i++]=源;
//G->节点[source.row][source.col]='*';
已访问[邻居行][邻居列]=灰色;
排队(尾波,邻居);
}
}
}
游离(尾波);
返回-1;
}
Graph initGraphMatrix(int行,int列){
int i;
图G=malloc(sizeof(struct TGraph));
G->nodes=malloc(rows*sizeof(char*));
对于(i=0;inodes[i]=malloc(cols*sizeof(char));
G->行=行;
G->cols=cols;
返回G;
}
void printGraphMatrix(图G){
如果(G!=NULL){
int i,j;
对于(i=0;irows;i++){
对于(j=0;jcols;j++)
putchar(G->nodes[i][j]);
putchar('\n');
}
}
}
int main(){
图G=初始图矩阵(11,21);
G->S.row=1;
G->S.col=1;
G->T.row=9;
G->T.col=7;
strcpy(G->nodes[0],“|----------------------------”号;
strcpy(G->nodes[1],“|S | | |””;
strcpy(G->nodes[2],“| |-|-|-|-|-|-|-|-|]”;
strcpy(G->nodes[3],“| | | | | | |””;
strcpy(G->nodes[4],“| | |-|-|-|-|-|-|”);
strcpy(G->nodes[5],“| | | | | | | |””;
strcpy(G->nodes[6],“| | | | | | |-| | | | |“”;
strcpy(G->nodes[7],“| | | | | | | |”);
strcpy(G->nodes[8],“| | | |-|-|-|-|-|-|-|-|-|]”;
strcpy(G->nodes[9],“| | T | |””;
strcpy(G->nodes[10],“|--------------------|”);
结构坐标pred[(G->rows*G->cols)];
印刷图形矩阵(G);
系统(“暂停”);
如果(BFSPathMatrix(G,pred)!=-1){
int i;
对于(i=0;irows*G->cols;i++){
if(pred[i].row==G->S.row&&pred[i].col==G->S.col)
继续;
if(pred[i].row==G->T.row&&pred[i].col==G->T.col)
打破
G->nodes[pred[i].row][pred[i].col]='*';
}
印刷图形矩阵(G);
}否则
看跌期权(“无法达到目标”);
系统(“暂停”);
返回0;
}
这是BFS前后迷宫的样子:

如何仅打印最短路径?为什么“T”前面的空格中没有“*”? 提前感谢您的宝贵时间。

Upd

我对我的代码和你的代码做了一点修改。您需要的
pred
数组不是作为数组,而是作为
[G->rows][G->col]
的矩阵大小。这个矩阵的每个细胞都显示了你来自哪个细胞!我认为您对这个想法理解不正确,您将
pred
数组填入
        if(neighbor.row == G->T.row && neighbor.col == G->T.col){
            pred[neighbor.row*G->cols + neighbor.col] = source;
            free(coda);
            return 1;
        }
        if(visited[neighbor.row][neighbor.col] == WHITE && G->nodes[neighbor.row][neighbor.col] == ' '){     //If it's undiscovered, we put it in the queue
            pred[neighbor.row*G->cols + neighbor.col] = source;
            visited[neighbor.row][neighbor.col] = GREY;
            enqueue(coda, neighbor);
        }
if(BFSPathMatrix(G, pred) != -1){
    struct coord T = G->T;
    int predInd = T.row*G->cols + T.col;
    while (pred[predInd].row != G->S.row || pred[predInd].col != G->S.col) {
        predInd = T.row*G->cols + T.col;
        T = pred[predInd];
        if( G->nodes[T.row][T.col] == ' ')
            G->nodes[T.row][T.col] = '*';
    }
    printGraphMatrix(G);
}else
    puts("Target unreachable");
|-------------------|
|S      |       |   |
| |-| |-| |---| | | |
| | |     |     | | |
| | |---| | |---| | |
| | |   | |   | | | |
| | | | |-| | | | | |
| | | |   | |     | |
| | | |-| |-------| |
|   |  T|           |
|-------------------|
Press any key to continue . . .
|-------------------|
|S****  |*******|***|
| |-|*|-|*|---|*|*|*|
| | |*****|*****|*|*|
| | |---| |*|---|*|*|
| | |***| |***| |*|*|
| | |*|*|-| |*| |*|*|
| | |*|***| |*****|*|
| | |*|-|*|-------|*|
|   |**T|***********|
|-------------------|