C 我使用bfs查找图中最短路径的代码不适用于循环

C 我使用bfs查找图中最短路径的代码不适用于循环,c,algorithm,breadth-first-search,C,Algorithm,Breadth First Search,我的任务是编写一个代码,使用“BFS”在图形中查找两个节点之间的最短路径。我给出了随机的输入,它工作得很好,直到我给出了一个循环的输入,它没有给出最短的路径,而是在这个循环上循环。 这是我的程序,它最多需要9个顶点(0到8),因为我在遍历每个节点分支后使用9作为分隔符 #include <stdio.h> #include <stdlib.h> #define MAX 100 int n, m = 0; int adj[MAX][MAX]; //adjacency m

我的任务是编写一个代码,使用“BFS”在图形中查找两个节点之间的最短路径。我给出了随机的输入,它工作得很好,直到我给出了一个循环的输入,它没有给出最短的路径,而是在这个循环上循环。 这是我的程序,它最多需要9个顶点(0到8),因为我在遍历每个节点分支后使用9作为分隔符

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

#define MAX 100

int n, m = 0;
int adj[MAX][MAX]; //adjacency matrix, where adj[i][j] = 1, denotes there is an  edge from i to j
int visited[MAX];  //visited[i] can be 0 or 1, 0 : it has not yet printed, 1 : it has been printed
int track[MAX];
void create_graph();
void BF_Traversal();
void BFS();

int queue[MAX], stack[MAX], track[MAX], front = -1, rear = -1, top = -1;
int track_size = 0, stack_size = 0;
void push_queue(int vertex);
int pop_queue();
int isEmpty_queue();
void push_track(int data);
void shortest_path();
void push(int p);
int pop();

int main()
{
    create_graph();  //Create a graph
    BFS();           //Traverse the graph in BFS keeping track of every node visited
    shortest_path(); //Print out the shortest path
    return 0;
}

void BFS()
{
    int v, src, des;

    for (v = 0; v < n; v++)
        visited[v] = 0;

    printf("Enter the source and destination nodes: ");
    scanf("%d%d", &src, &des);
    v = src;

    int i;

    push_queue(v); //A queue is for the normal bfs algorithm
    push_track(9); // this array is to track all the nodes visited

    while (!isEmpty_queue())
    {

        v = pop_queue();
        if(visited[v])
        continue;
        push_track(v);
        visited[v] = 1;

        for (i = 0; i < n; i++)
        {
            if (adj[v][i] == 1)
                push_track(i);
            if (adj[v][i] == 1 && i == des)
                return;
            if (adj[v][i] == 1 && visited[i] == 0)
            {
                push_queue(i);
            }
        }
        push_track(9);//I used 9 as a separator after each node traversal, so the max vertices is 9(0-8) 
    }
    printf("\n");
}

void push_queue(int vertex)
{
    if (rear == MAX - 1)
        printf("Queue Overflow\n");
    else
    {
        if (front == -1)
            front = 0;
        rear = rear + 1;
        queue[rear] = vertex;
    }
}

int isEmpty_queue()
{
    if (front == -1 || front > rear)
        return 1;
    else
        return 0;
}

int pop_queue()
{
    int delete_item;
    if (front == -1 || front > rear)
    {
        printf("Queue Underflow\n");
        exit(1);
    }

    delete_item = queue[front];
    front = front + 1;
    return delete_item;
}

void push(int p)
{
    top++;
    stack[top] = p;
    stack_size++;
}

int pop()
{
    return stack[top--];
}

void push_track(int data)
{
    track[m] = data;
    m++;
    track_size++;
}

void shortest_path()
{
    push(9); //using a stack for arranging the shortest path from the tracking array
    push(track[track_size - 1]);
    int a, i, j, first = 1;
    for (i = track_size - 1; i >= 0; i--)
    {
        if (track[i] == 9 && first == 1)
        {
            a = i + 1;
            push(track[a]);
            first = 0;
            continue;
        }
        if (track[i] == track[a])
        {
            for (j = i; j >= 0; j--)
            {
                if (track[j] == 9)
                {
                    a = j + 1;
                    push(track[a]);
                    i = i - (i - j);
                    break;
                }
            }
        }
    }
    for (i = 0; i < stack_size - 1; i++)
    {
        int q = pop();
        if (q == 9)
            break;
        printf("%d ", q);
    }
}

void create_graph()
{
    int count, max_edge, origin, destin;

    printf("Enter number of vertices : ");
    scanf("%d", &n);
    max_edge = n * (n - 1); //assuming each vertex has an edge with remaining (n-1) vertices

    for (count = 1; count <= max_edge; count++)
    {
        printf("Enter edge %d( -1 -1 to quit ) : ", count);
        scanf("%d %d", &origin, &destin);

        if ((origin == -1) && (destin == -1))
            break;

        if (origin >= n || destin >= n || origin < 0 || destin < 0)
        {
            printf("Invalid edge!\n");
            count--;
        }
        else
        {
            adj[origin][destin] = 1;
            adj[destin][origin] = 1; // assuming it is a bi-directional graph, we are pushing the reverse edges too.
        }
    }
}
输出不正确的示例

Enter number of vertices : 6
Enter edge 1( -1 -1 to quit ) : 0 1
Enter edge 2( -1 -1 to quit ) : 0 3
Enter edge 3( -1 -1 to quit ) : 1 2
Enter edge 4( -1 -1 to quit ) : 2 3
Enter edge 5( -1 -1 to quit ) : 2 4
Enter edge 6( -1 -1 to quit ) : 3 5
Enter edge 7( -1 -1 to quit ) : -1 -1
Enter the source and destination nodes: 4 5
4 2 3 5
Enter number of vertices : 5
Enter edge 1( -1 -1 to quit ) : 0 1
Enter edge 2( -1 -1 to quit ) : 0 2
Enter edge 3( -1 -1 to quit ) : 1 2
Enter edge 4( -1 -1 to quit ) : 2 3
Enter edge 5( -1 -1 to quit ) : 3 4
Enter edge 6( -1 -1 to quit ) : -1 -1
Enter the source and destination nodes: 0 3
0 1 2 3
如果在语句中:

if (track[i] == 9 && first == 1)
if (track[i] == track[a])
tract[i]
不等于
9
则在语句中:

if (track[i] == 9 && first == 1)
if (track[i] == track[a])
a
尚未初始化。这将导致未定义的行为,因为此时
a
可以是任何内容,从而在循环中导致不可预知的结果

这里的主要建议是初始化所有变量。

第二步是将编译器设置为显示所有警告,然后按照它的建议进行操作。

答案与C无关,但与算法无关。一种方法是记录您在遍历中的位置,每次访问新节点时,检查是否已经访问过它。如果你有,那就不要走那条路。我没有仔细阅读您的代码,但是如果您已经处理了这些问题,并且您的实现中有一个bug,那么请提供一些详细信息,说明到目前为止您在调试代码方面做了哪些工作。编辑您的文章以添加新的澄清信息或改进格式是很好的。但是,不建议编辑以更正注释或答案中已经提到的代码,因为这会给试图帮助解决问题的人带来移动的目标,并给以后查看问题的人带来混乱。请避免进行此类编辑。我已将该编辑回滚到以前的状态。
if(track[I]==9&&first==1)
这始终是正确的,因为我只使用它存储最后一个变量,但只有一个变量。但是我把a改成了a=0@Gagankaranth-请参阅我在您的帖子下关于编辑答案的评论。使用调试器逐步检查代码将有助于识别逻辑流的缺陷。