Dijkstra的无加权图算法

时间:2018-09-28 09:44:21

标签: c algorithm data-structures graph

该程序用于在未加权图中查找最短路径。我在结构int **weight中使用了graph。我必须找到从源顶点到任何其他顶点v的最小距离。就像Dijkstra的非加权图一样。

我要得到几乎正确的输出,除了最后一个顶点4,它涉及到双端队列4并退出处理循环。

#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;
    int **weight;
    struct adjlist* array;
};

int visited[100];
int distance[100],path[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("\n enqueing %d \n",queue->array[queue->rear]);
        return;
    }
    queue->rear=(queue->rear+1)%queue->capacity;
    queue->array[queue->rear]=data;
    printf("\n enqueuing %d \n",queue->array[queue->rear]);
}

int dequeue(struct Queue* queue){
    if(isempty(queue)){
        printf("\nreturning queue is empty\n");
        return -1;
    }
    if(queue->front==queue->rear){
        int temp=queue->front;
        queue->rear=-1;
        queue->front=-1;
        printf("\n front and rear are equal dequeing  %d \n",queue->array[temp]);
        return queue->array[temp];
    }
    else{
        int temp=queue->front;
        queue->front=(queue->front+1)%queue->capacity;
        printf("\ndequeuing %d \n",queue->array[temp]);
        return (queue->array[temp]);
    }
}

int isfront(struct Queue* queue){
    return(queue->array[queue->front]);
}

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));
    G->weight=malloc(v*sizeof(int*));
    for(int j=0;j<v;j++)
        G->weight[j]=malloc(sizeof(int)*v);
    for(int i=0;i<v;i++)
        G->array[i].head=NULL;
    return G;
}

struct adjlistnode* getnewnode(int dest){
    struct adjlistnode* newnode = malloc(sizeof(struct adjlistnode*));
    newnode->dest=dest;
    newnode->next=NULL;
    return newnode;
}

void addedge(struct graph* G,int src ,int dst){
    struct adjlistnode* temp = getnewnode(dst);
    temp->next = G->array[src].head;
    G->array[src].head=temp;

    printf(" \n enter the weight \n ");
    int n;
    scanf("%d",&n);
    G->weight[src][dst]=n;
    G->weight[dst][src]=n;
}

void shpu(struct graph* G,struct Queue* queue,int s){
    int v,w;
    enqueue(queue,s);
    distance[s]=0;
    while(!isempty(queue)){
        v=dequeue(queue);
        struct adjlistnode* temp = G->array[v].head;
        while(temp!=NULL){
            if(distance[temp->dest]==-1){
                printf("\ntemp->dest = %d \n",temp->dest);
                printf("\n v is %d \n",v);
                distance[temp->dest]=distance[v] + 1;
                path[temp->dest]=v;
                enqueue(queue,temp->dest);
            }
            temp=temp->next;
        }
    }
}

int main(){
    struct graph* G = creategraph(5);
    struct Queue* queue = createqueue(100);
    addedge(G,0,1);
    addedge(G,1,2);
    addedge(G,3,4);
    addedge(G,2,3);
    addedge(G,4,1);
    for(int i=0;i < 100;i++){
        distance[i]=-1;
    }

    shpu(G,queue,1);
    for(int i=0;i<100;i++){
        printf(" %d ",path[i]);
    }
}

1 个答案:

答案 0 :(得分:0)

通常在Dijkstra的队列中,您的队列需要按权重的降序保留边缘的信息。但是,既然您的权重是0,那么您就可以开始做任何事情(BFS)。

您在addHead()的过程中出错。在前三行中,您要从srcdst添加一个无方向的边,但是相反发生了什么呢? 因此,也只需将dst添加到src,您应该就可以了。

void addedge(struct graph* G,int src ,int dst){
    struct adjlistnode* temp = getnewnode(dst);
    temp->next = G->array[src].head;
    G->array[src].head=temp;            // Add src to dst
    struct adjlistnode* temp2 = getnewnode(src);
    temp2->next = G->array[dst].head;
    G->array[dst].head = temp2;        // Add dst to src

    ...
}