You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

顶点信息赋值时出现访问权限冲突的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 12:26:13