【问题标题】:Implementation of BFS using queue and adjacency list in CC中使用队列和邻接表实现BFS
【发布时间】:2019-09-26 15:00:18
【问题描述】:

我正在解决一个允许两种类型操作的问题:从一个数字中减去一个或将它乘以 2,并提供源数字和目标数字。两个数字的输入约束为 1

#include <stdio.h>
#include <stdlib.h>
int g[22222][3], v[2222], size;//g == graph, v == visited and size == the size of queue
typedef struct _queue
{
    int val;
    struct _queue *next;
    struct _queue *prev;
} queue;
queue *head=NULL, *last=NULL;
void push(int val)
{
    queue *ptr=(queue *) malloc(sizeof(queue));
    ptr->next=NULL;
    ptr->val=val;
    if (head)
    {
        last->next=ptr;
        ptr->prev=last;
    }
    else
    {
        head=ptr;
        ptr->prev=NULL;
    }
    last=ptr;
}
void pop()
{
    if (size)
    {
        queue *ptr=last;
        last=last->prev;
        if (head) last->next=NULL;
        free(ptr);
    }
}
int front() {return last->val;}
int bfs(int s, int d)//s == source and d == destination
{
    int cnt=0;
    push(s);
    size++;
    v[s]=1;
    while (size)
    {
        int u=front();
        pop();
        size--;
        for (int j=1; j<=2; j++)
        {
            if (d==g[u][j]) return (cnt+1);
            if (!v[g[u][j]])
            {
                v[g[u][j]]=1;
                size++;
                push(g[u][j]);
            }
        }
        cnt++;
    }
}
int main()
{
    int n, m, val;
    scanf("%d%d", &n, &m);
    if (n==m) {printf("0"); return 0;}
    val=(n>m?n:m)*2;
    v[0]=1;
    for (int i=1; i<=val; i++)
    {
        g[i][1]=2*i;
        g[i][2]=i-1;
    }
    printf("%d", bfs(n, m));
    return 0;
}

【问题讨论】:

    标签: c graph queue breadth-first-search


    【解决方案1】:

    您已经实现了一个堆栈,即 LIFO(后进先出):您正在添加到末尾并从末尾检索。

    你应该实现一个队列,即FIFO(先进先出),所以如果你添加到末尾,你应该从前面检索:

    void pop()
    {
        if (size)
        {
            queue *ptr=head;
            head=head->next;
            if (head) head->prev=NULL;
            free(ptr);
        }
    }
    int front() 
    {
       return head->val;
    }
    

    另外,我想您的目标是计算从给定操作中产生所需数字所需的 最小 操作数。您的 cnt 变量并不代表最少的操作次数,它代表您从队列中检索元素的次数。您需要为每个 新级别 增加它。

    最后,即使没有从s 到d 的路径,您的bfs 也应该返回一个值,因此您应该将return 0; 放在while(size){} 循环之后。

    UPD。如果g[u][j] 在bfs 内大于2 * (10^4),则需要跳过它,否则这些值会被排入队列,这会浪费空间。顺便说一句,您的 v 数组只有 2222 个元素,它应该至少有 20001 个(v[20000] 是最后一个)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-08-29
      • 1970-01-01
      • 2012-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-28
      相关资源
      最近更新 更多