kavinderrana121 Ответов: 1

Обход Bfs с использованием C


В данный момент я изучаю графики и использую C. Когда я представляю граф со списком смежности, мне нужна очередь для обхода BFS. Однако у меня возникли некоторые проблемы с кодом - я не уверен, что хорошо понял концепцию обхода bfs с очередями.

Я вставил прокомментированный код ниже, надеюсь, он читабелен. Может ли кто-нибудь проверить это или, по крайней мере, предоставить некоторую информацию о том, как это сделать правильно?

программа терпит крах, а также показывает ошибку сегментации

Что я уже пробовал:

    #include<stdio.h>
    #include<stdlib.h>
    struct Queue{
        int rear;
        int front;
        int capacity;
        int* array;
    };
    struct adjlistnode{
        int dest;
        struct adjlistnode* next;
    };
    struct adjlist{
        struct adjlistnode* head;
    };
    struct graph{
        int V;
        struct adjlist* array;
    };
    int visited[100];

    struct Queue* createqueue(int capacity){
        struct Queue* queue=(struct Queue*)malloc(sizeof(struct Queue));
        queue->rear = -1;
        queue->front = -1;
    queue->capacity=capacity;
    queue->array=(int*)malloc(sizeof(int)*capacity);
    return queue;
    }
    int isempty(struct Queue* queue){
        return(queue->front==-1 && queue->rear==-1);
    }
    void enqueue(struct Queue* queue,int data){
        if(isempty(queue)){
            queue->rear=0;
            queue->front=0;
            queue->array[queue->rear]=data;
            printf("%d",queue->array[queue->rear]);
            return;
        }
    queue->rear=(queue->rear+1)%queue->capacity;
    queue->array[queue->rear]=data;
    } 
    int dequeue(struct Queue* queue){
        if(isempty(queue))
            return -1;
        int temp=queue->front;
        queue->front=(queue->front+1)%queue->capacity;
        return (queue->array[temp]); 
    }
    int isfront(struct Queue* queue){
        return(queue->array[queue->front]);
    }
/// GRAPH FUNCTIONS
    struct adjlistnode* getnewnode(int dest){
        struct adjlistnode* newnode =(struct adjlistnode*)malloc(sizeof(struct adjlistnode));
        newnode->dest=dest;
        newnode->next=NULL;
        return newnode;
    }
    struct graph* creategraph(int V){
        struct graph* G = (struct graph*)malloc(sizeof(struct graph));
        G->V=V;
        G->array=(struct adjlist*)malloc(V*sizeof(struct adjlist));
        for(int i=0;i<V;i++){
            G->array[i].head=NULL;
        }
     return G;
    }
    void addedge(struct graph* G,int src ,int dest){
        struct adjlistnode* newnode=getnewnode(dest);

        newnode->next=G->array[src].head;
        G->array[src].head=newnode; 

        newnode=getnewnode(src);
 
        newnode->next=G->array[dest].head;
        G->array[dest].head=newnode;
    }
    void printgraph(struct graph* G){
        for(int i=0;i<G->V;i++){
            struct adjlistnode* temp=G->array[i].head;
            while(temp!=NULL){
                printf("%d",temp->dest);
                temp=temp->next;
            }
            printf("\n");
        }
    }
    void bfs(struct graph* G,struct Queue* queue,int startvertex){


        enqueue(queue,startvertex);


        while(!isempty(queue)){
           int u=dequeue(queue);
           visited[u]=1;
           printf(" \n %d ",u);
           struct adjlistnode* temp=G->array[u].head;
           while(temp){
             if(visited[temp->dest]==0){
                 visited[temp->dest]=1;
                 enqueue(queue,temp->dest);
              }
           temp=temp->next;
           }

        }

    }
    void bfstraversal(struct graph* G,struct Queue *queue){
        int i;
        for(i=0;i<G->V;i++)
            visited[i]=0;
        for(i=0;i<G->V;i++){
            if(!visited[i]){
                bfs(G,queue,i);
            }
        }
    }
     int main(){
        struct Queue* queue=createqueue(100);
        enqueue(queue,1);
        enqueue(queue,2);
        printf("\n%d",dequeue(queue));
        printf("\n%d",dequeue(queue));
        struct graph* G=creategraph(5);
        addedge(G,1,2);
        addedge(G,1,1);
        printgraph(G);
        bfstraversal(G,queue);
      //  printf("\n%d",dequeue(queue));
    }

1 Ответов

Рейтинг:
12

OriginalGriff

Компиляция не означает, что ваш код верен! :смеяться:
Подумайте о процессе разработки как о написании электронного письма: успешная компиляция означает, что вы написали письмо на правильном языке - например, на английском, а не на немецком, - а не то, что письмо содержало сообщение, которое вы хотели отправить.

Итак, теперь вы входите во вторую стадию разработки (на самом деле это четвертая или пятая, но вы перейдете к более ранним стадиям позже): тестирование и отладка.

Начните с рассмотрения того, что он делает, и как это отличается от того, что вы хотели. Это важно, потому что это дает вам информацию о том, почему он это делает. Например, если программа предназначена для того, чтобы позволить пользователю ввести число, а затем удвоить его и напечатать ответ, то если бы ввод / вывод был таким:

Input   Expected output    Actual output
  1            2                 1
  2            4                 4
  3            6                 9
  4            8                16
Тогда совершенно очевидно, что проблема заключается в бите, который удваивает его - он не прибавляет себя к себе или умножает его на 2, он умножает его на себя и возвращает квадрат входного сигнала.
Таким образом, вы можете посмотреть на код, и очевидно, что он находится где-то здесь:
int Double(int value)
   {
   return value * value;
   }

Как только у вас появится идея, что может пойти не так, начните использовать отладчик, чтобы выяснить, почему. Поместите точку останова в первую строку метода и запустите приложение. Когда он достигнет точки останова, отладчик остановится и передаст управление вам. Теперь вы можете запускать свой код построчно (так называемый "одноступенчатый") и просматривать (или даже изменять) содержимое переменных по мере необходимости (черт возьми, вы даже можете изменить код и повторить попытку, если вам это нужно).
Подумайте о том, что должна делать каждая строка кода перед ее выполнением, и сравните это с тем, что она действительно делала, когда вы использовали кнопку "Step over" для выполнения каждой строки по очереди. Он сделал то, что вы ожидали? Если да, то переходите к следующей строке.
Если нет, то почему? Чем это отличается?
Надеюсь, это поможет вам определить, в какой части этого кода есть проблема и в чем она заключается.
Это навык, и его стоит развивать, поскольку он помогает вам как в реальном мире, так и в развитии. И, как и все навыки, он только улучшается при использовании!