【发布时间】:2021-07-10 11:24:13
【问题描述】:
我正在尝试使用邻接列表和 PQ 作为最小堆来实现单目的地最短路径的 Dijkstra 算法。输出必须显示所有顶点到目标顶点的路径,如果路径存在,如果存在,则它的总和(最短),如果不存在,则没有路径。 Link to entire code
输入格式:
- 第一行是顶点数,n
- 从第二行开始:(顶点从 1 到 n)
- 第一列是顶点。
- 之后,多对,
- test.txt
4
1 2 4 3 5 4 5
4 1 7 3 3
2 1 3 4 10
根据 GDB 显示,在 extractMin 函数中发现了 Segmentation fault。
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);
}
服务器.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");
}
}
【问题讨论】:
-
如果我们不知道代码实际出错的地方,
dijkstra的输入是什么,我们将无法为您提供太多帮助。 -
如果你没看到,我把整个代码链接放了。我应该显示 valgrind 显示的内容吗?
-
我在 VSCode 上尝试了 gdb,它在 extractMin 中抛出了 seg 错误,我将编辑帖子
-
编辑帖子以在帖子中提供minimal reproducible example。链接可用于补充信息,但重现问题所需的所有信息都应包含在问题本身中。 Stack Overflow 不是个人调试服务。它旨在创建一个持久的问题和答案存储库,以帮助未来的读者。但是到外部站点的链接会中断,从而使依赖于它们的问题对其他人毫无用处。所以一切都必须在帖子中。调试你的程序是一个附带的好处,而要求调试大量代码是一种滥用。
标签: c algorithm segmentation-fault dijkstra