C Dijkstra-SDSP算法

C Dijkstra-SDSP算法,c,algorithm,segmentation-fault,dijkstra,C,Algorithm,Segmentation Fault,Dijkstra,我尝试使用邻接列表和PQ作为最小堆来实现单目的地最短路径的Dijkstra算法。输出必须显示所有顶点到目标顶点的路径(如果路径存在),如果是,则显示其总和(最短),如果否,则显示无路径。 输入格式: 第一行是顶点数,n 第二行开始:(顶点从1到n) 第一列是顶点 之后,多对 test.txt 根据GDB,它显示在extractMin函数中发现的分段错误 Program received signal SIGSEGV, Segmentation fault. 0x00401746 in

我尝试使用邻接列表和PQ作为最小堆来实现单目的地最短路径的Dijkstra算法。输出必须显示所有顶点到目标顶点的路径(如果路径存在),如果是,则显示其总和(最短),如果否,则显示无路径。

输入格式:

  • 第一行是顶点数,n
  • 第二行开始:(顶点从1到n)
    • 第一列是顶点
    • 之后,多对
  • test.txt
根据GDB,它显示在extractMin函数中发现的分段错误

Program received signal SIGSEGV, Segmentation fault.
0x00401746 in extractMin ()
客户c

从text.txt文件中提取输入并创建有向图

FILE *fptr = fopen("test.txt", "r");
    if (fptr == NULL) exit(1);

    int n;
    if (fscanf(fptr, "%d", &n) == 1 && n > 0)
    {
        Graph *graph = createGraph(n);
        int c;
        while ((c = fgetc(fptr)) != EOF && c != '\n');
        char *line = NULL;      
        size_t len = 0;        

        while (getline(&line, &len, fptr) > 0)
        {
            char *cur = line;
            int ccs = 0;
            int v1;

            if (sscanf(cur, "%d%n", &v1, &ccs) == 1)
            {
                cur += ccs;
                int v2;
                int w;
                while (sscanf(cur, "%d %d%n", &v2, &w, &ccs) == 2)
                {
                    addEdge(graph, v1, v2, w);
                    cur += ccs;
                }

                fputc('\n', stdout);
            }

        }
        free(line);
        for (int i = 0; i < n; i++)
            dijkstra(graph, i);
    }
FILE*fptr=fopen(“test.txt”、“r”);
如果(fptr==NULL)退出(1);
int n;
如果(fscanf(fptr,%d,&n)==1&&n>0)
{
Graph*Graph=createGraph(n);
INTC;
而((c=fgetc(fptr))!=EOF&c!='\n');
char*line=NULL;
尺寸长度=0;
而(getline(&line,&len,fptr)>0)
{
char*cur=行;
int=0;
int v1;
如果(sscanf(cur,%d%n,&v1,&ccs)==1)
{
cur+=ccs;
int v2;
int w;
而(sscanf(cur、%d%d%n、&v2、&w和&ccs)==2)
{
加法(图,v1,v2,w);
cur+=ccs;
}
fputc('\n',stdout);
}
}
自由线;
对于(int i=0;i
服务器.c

struct MinHeapNode* extractMin(MinHeap* minHeap)
{
    if (isEmpty(minHeap))
        return NULL;
 
    struct MinHeapNode* root = minHeap->array[0];
    struct MinHeapNode* lastNode = minHeap->array[minHeap->size - 1];
    minHeap->array[0] = lastNode;
 
    minHeap->pos[root->v] = minHeap->size-1;
    minHeap->pos[lastNode->v] = 0;
 
    --minHeap->size;
    minHeapify(minHeap, 0);
 
    return root;
}
void dijkstra(Graph* graph, int dest)
{
    int v = graph->vertices;
    int distance[v]; 
    int pathFollow[1000]={0};
    int ind = 0;

    MinHeap* minHeap = createMinHeap(v);
 
    for (int i = 0; i < v; ++i)
    {
        distance[v] = INT_MAX;
        minHeap->array[v] = newMinHeapNode(v, distance[v]);
        minHeap->pos[v] = v;
    }
 
    minHeap->array[dest] = newMinHeapNode(dest, distance[dest]);
    minHeap->pos[dest] = dest;
    distance[dest] = 0;
    decreaseKey(minHeap, dest, distance[dest]);
 
    minHeap->size = v;

    while (!isEmpty(minHeap))
    {
        struct MinHeapNode* minHeapNode = extractMin(minHeap);
        int u = minHeapNode->v;
        AdjListNode* path = graph->array[u].head;
        while (path != NULL)
        {
            int v = path->vertex;
            if (isInMinHeap(minHeap, v) && distance[u] != INT_MAX &&
              path->weight + distance[u] < distance[v])
            {
                distance[v] = distance[u] + path->weight;
                if(pathFollow[ind-1] != u)
                    pathFollow[ind++]=u;
                decreaseKey(minHeap, v, distance[v]);
            }
            path = path->next;
        }
    }
    printArr(distance, v, pathFollow, dest);
}

void printArr(int dist[], int n, int pathFollow[], int dest)
{
    printf("%d", dest+1);
    int j = 0;
    if(dist[n-1]!=0 && dist[n-1] < 100000000) 
    {
        int k = j;
        printf(" %d", pathFollow[k]+1);
        while(pathFollow[j]!=0) 
        {
        printf(" %d", pathFollow[j++]);
        }
        printf(" %d %d\n",n, dist[n-1]);
    }
    else
    {
        printf("NO PATH\n");
    }
}


struct MinHeapNode*extractMin(MinHeap*MinHeap)
{
如果(isEmpty(minHeap))
返回NULL;
结构MinHeapNode*root=minHeap->array[0];
结构MinHeapNode*lastNode=minHeap->array[minHeap->size-1];
minHeap->array[0]=lastNode;
minHeap->pos[root->v]=minHeap->size-1;
minHeap->pos[lastNode->v]=0;
--minHeap->size;
minHeapify(minHeap,0);
返回根;
}
void dijkstra(图*图,int dest)
{
int v=图形->顶点;
整数距离[v];
int-pathFollow[1000]={0};
int ind=0;
MinHeap*MinHeap=createMinHeap(v);
对于(int i=0;iarray[v]=newMinHeapNode(v,距离[v]);
minHeap->pos[v]=v;
}
minHeap->array[dest]=newMinHeapNode(dest,distance[dest]);
minHeap->pos[dest]=dest;
距离[dest]=0;
递减键(最小堆、目标、距离[dest]);
minHeap->size=v;
而(!isEmpty(minHeap))
{
结构MinHeapNode*MinHeapNode=extractMin(minHeap);
int u=minHeapNode->v;
AdjListNode*路径=图形->数组[u]。头部;
while(路径!=NULL)
{
int v=路径->顶点;
如果(isInMinHeap(minHeap,v)&距离[u]!=INT\u MAX&&
路径->重量+距离[u]<距离[v])
{
距离[v]=距离[u]+路径->重量;
if(路径跟随[ind-1]!=u)
路径跟随[ind++]=u;
递减键(minHeap,v,距离[v]);
}
路径=路径->下一步;
}
}
printArr(距离、v、路径跟踪、目的地);
}
void printArr(int dist[],int n,int path follow[],int dest)
{
printf(“%d”,dest+1);
int j=0;
如果(距离[n-1]!=0和距离[n-1]<100000000)
{
int k=j;
printf(“%d”,路径跟随[k]+1);
while(路径跟随[j]!=0)
{
printf(“%d”,路径跟随[j++]);
}
printf(“%d%d\n”,n,dist[n-1]);
}
其他的
{
printf(“无路径”);
}
}

我不打算调试整个程序,但这里有几个错误:

  • 你创造

     Graph *graph = createGraph(n);
    
  • 然后访问
    图形->数组[src].head

    这是一个问题,因为
    n
    只是顶点总数,在您的示例4中,但当使用类似
    4 1 7
    的内容调用该
    addEdge()
    时,这是一个堆缓冲区溢出。您需要考虑创建的
    0索引
    数组

  • 另一个溢出问题,这次是堆栈缓冲区,位于:

    int v = graph->vertices;
    int distance[v];
    
  • 但这被称为

    distance[v] = INT_MAX;
    
    同样,不考虑
    0索引的
    数组。此外,该代码似乎可疑,我认为应该是
    distance[i]=INT\u MAX


    请检查您自己的代码以了解更多此类错误,尤其是数组索引溢出,使用检查代码中的内存错误,逐步检查程序的每一行,并查看是否确实发生了预期的情况。您提到了
    extractMin()
    中的程序错误。检查它是否正在访问它应该访问的内存<代码>SIGSEGV
    表示非法内存访问。
    struct MinHeapNode*root
    是否指向您分配的内容?
    struct MinHeapNode*lastNode
    是否指向您分配的内容?

    尝试通过在代码中添加断点(这里是a)来运行代码,看看问题出在哪里。在我们不知道代码实际发生故障的情况下,
    dijkstra
    的输入是什么,我们帮不了你多少忙。如果你没看到,我会把整个代码链接都放进去。我应该展示valgrind展示的内容吗?我在VSCode上尝试了gdb,它在extractMin中抛出了seg错误,我将编辑帖子编辑帖子以在帖子中提供一个。链接可用于补充信息,但重现问题所需的所有信息都应在问题本身中。堆栈溢出不是个人调试服务。它旨在创建一个持久的问题和答案库,以帮助未来的读者。但与外部网站的链接中断,使得依赖这些链接的问题对其他人毫无用处。所以所有的东西都必须在岗位上。调试你的程序是一个附带的好处,而要求调试大量的代码是一种滥用。我当然会试试看
    distance[v] = INT_MAX;