顶点信息赋值时出现访问权限冲突的DFS代码修复求助
邻接表实现DFS算法的访问权限冲突修复方案
问题定位
e->adjvex=j触发访问权限冲突,核心原因是边节点指针e未被正确分配内存,属于野指针操作。邻接表构建过程中,每一条边都需要对应一个独立的边节点,必须先通过动态内存分配获取合法内存空间,再进行赋值操作。
修复后的完整代码
#include <stdio.h> #include <stdlib.h> #include <string.h> // 边节点结构体 typedef struct EdgeNode { int adjvex; // 邻接点的索引 struct EdgeNode *next; // 下一条边的指针 } EdgeNode; // 顶点结构体 typedef struct VertexNode { char data; // 顶点数据 EdgeNode *firstedge; // 指向第一条边的指针 } VertexNode, AdjList[100]; // 邻接表数组 // 图结构体 typedef struct { AdjList adjList; int numVertices, numEdges; // 顶点数、边数 } GraphAdjList; // 访问标记数组 int visited[100]; // 初始化图 void InitGraph(GraphAdjList *G) { int i; G->numVertices = 0; G->numEdges = 0; for (i = 0; i < 100; i++) { G->adjList[i].firstedge = NULL; visited[i] = 0; } } // 构建邻接表 void CreateGraph(GraphAdjList *G) { int i, j, k; EdgeNode *e; printf("请输入顶点数和边数:"); scanf("%d%d", &G->numVertices, &G->numEdges); getchar(); // 吸收换行符 // 输入顶点信息 for (i = 0; i < G->numVertices; i++) { printf("请输入第%d个顶点的信息:", i+1); scanf("%c", &G->adjList[i].data); getchar(); G->adjList[i].firstedge = NULL; } // 输入边信息 for (k = 0; k < G->numEdges; k++) { printf("请输入边(vi,vj)的顶点序号:"); scanf("%d%d", &i, &j); // 为边节点分配内存 e = (EdgeNode *)malloc(sizeof(EdgeNode)); if (!e) { printf("内存分配失败!\n"); exit(1); } // 设置邻接点(转换为数组索引,假设输入序号从1开始) e->adjvex = j-1; // 将边节点挂载到i顶点的邻接表头部 e->next = G->adjList[i-1].firstedge; G->adjList[i-1].firstedge = e; // 无向图需要添加反向边 e = (EdgeNode *)malloc(sizeof(EdgeNode)); if (!e) { printf("内存分配失败!\n"); exit(1); } e->adjvex = i-1; e->next = G->adjList[j-1].firstedge; G->adjList[j-1].firstedge = e; } } // 深度优先遍历 void DFS(GraphAdjList *G, int i) { EdgeNode *p; printf("%c ", G->adjList[i].data); visited[i] = 1; p = G->adjList[i].firstedge; while (p) { if (!visited[p->adjvex]) { DFS(G, p->adjvex); } p = p->next; } } // 释放图内存 void FreeGraph(GraphAdjList *G) { int i; EdgeNode *p, *q; for (i = 0; i < G->numVertices; i++) { p = G->adjList[i].firstedge; while (p) { q = p; p = p->next; free(q); } } } int main() { GraphAdjList G; InitGraph(&G); CreateGraph(&G); printf("深度优先遍历结果:"); DFS(&G, 0); printf("\n"); FreeGraph(&G); return 0; }
关键修改说明
- 为边节点分配内存:每次添加边时,通过
malloc为e申请内存,并检查分配是否成功,彻底解决野指针问题 - 索引转换:将输入的顶点序号(通常从1开始)转换为数组索引(从0开始),避免数组越界
- 无向图双向边处理:无向图的每条边需要在两个顶点的邻接表中都添加对应的边节点,保证遍历逻辑正确
- 内存释放:新增
FreeGraph函数,遍历释放所有边节点内存,避免内存泄漏 - 输入处理:用
getchar吸收输入后的换行符,防止后续字符读取异常
内容的提问来源于stack exchange,提问作者欧-aita
相关产品推荐
相关产品推荐

