美文网首页
图(邻接表)

图(邻接表)

作者: lkmc2 | 来源:发表于2018-08-16 12:30 被阅读19次

邻接表:使用数组和链表相结合的存储方式。数组存储顶点信息,链表存储边信息;数组中每个节点(顶点)带一个指针,指向该顶点对应的边链表的头节点。

无向图 邻接表示意图

实现代码如下:

// 图(邻接表)
#include <stdio.h>
#include <malloc.h>

#define MAXVEX 100 // 最大顶点数

typedef char VertexType; // 顶点类型
typedef int EdgeType; // 边上的权值类型

// 边表节点
typedef struct EdgeNode {
    int adjvex; // 邻接点域,存储该顶点对应的下标
    EdgeType info; // 用来存储权值(非网图可没有)
    struct EdgeNode *next; // 指向下一个邻接点
} EdgeNode;

// 顶点表节点
typedef struct VertexNode {
    VertexType data; // 顶点域,存储顶点信息
    EdgeNode *firstEdge; // 边表头指针
} VertexNode, AdjList[MAXVEX];

// 邻接表结构
typedef struct {
    AdjList adjList;// 顶点表数组
    int numNodes, numEdges; // 图中当前顶点数,边数
} GraphAdjList;

/**
 * 创建邻接表
 * @param G 邻接表
 */
void CreateALGraph(GraphAdjList *G) {
    int i, j, k; // 用来遍历元素
    EdgeNode *e; // 边表节点

    printf("输入顶点数和边数:\n");
    scanf("%d,%d", &G->numNodes, &G->numEdges);
    getchar(); // 用来抵消回车

    printf("输入%d个顶点的信息:\n", G->numNodes);

    // 读取所有顶点的信息
    for (i = 0; i < G->numNodes; i++) {
        scanf("%c", &G->adjList[i].data); // 读取顶点信息
        getchar(); // 用来抵消回车

        G->adjList[i].firstEdge = NULL; // 将边表置为空表
    }

    // 读取所有边的信息
    for (k = 0; k < G->numEdges; k++) {
        printf("第%d条边:输入边(vi,vj)上的顶点序号:\n", k + 1);
        scanf("%d,%d", &i, &j); // 读取起点、终点序号
        getchar(); // 用来抵消回车

        e = (EdgeNode *) malloc(sizeof(EdgeNode)); // 为边表节点分配存储空间
        e->adjvex = j; // 邻接序号为j
        e->next = G->adjList[i].firstEdge; // 将e的指针指向当前顶点上指向的节点
        G->adjList[i].firstEdge = e; // 将当前顶点的指针指向e

        e = (EdgeNode *) malloc(sizeof(EdgeNode)); // 为边表节点分配存储空间
        e->adjvex = i; // 邻接序号为i
        e->next = G->adjList[j].firstEdge; // 将e的指针指向当前顶点上指向的节点
        G->adjList[j].firstEdge = e; // 将当前顶点的指针指向e
    }
}

/**
 * 打印邻接表
 * @param G 邻接表
 */
void Print(GraphAdjList *G) {
    int i, j; // 用来遍历元素
    EdgeNode *p;

    printf("顶点表的值为:\n");
    // 打印顶点表
    for (i = 0; i < G->numNodes; i++) {
        printf("v%d: %c\n", i, G->adjList[i].data);
    }

    printf("边表的值为:\n");
    for (i = 0; i < G->numNodes; i++) {
        printf("v%d ", i);

        p = G->adjList[i].firstEdge; // p指向顶点i的边表

        while (p) { // 边表未遍历完
            printf("-> %d", p->adjvex); // 打印邻接点
            p = p->next; // p移动到下一个边表节点
        }
        printf("\n");
    }
}

int main() {
    GraphAdjList G; // 邻接表
    CreateALGraph(&G); // 创建邻接表
    Print(&G); // 打印邻接表

    return 0;
}
运行结果

相关文章

  • Java数据结构 - 图(邻接表存储)

    邻接表 相比邻接矩阵,邻接表要更加节省空间。 邻接表存储 本文将介绍邻接表存储有向带权图。图的例子如下。 介绍一下...

  • 面试准备之【数据结构】1——图

    一. 有向图/无向图 共有:邻接表,邻接矩阵 有向图独有:十字链表,边集数组 无向图独有:邻接多重表 1.邻接矩...

  • 数据结构-图

    数据结构 - 图 目录: 基本概念无向图有向图 储存结构邻接矩阵邻接表十字链表(有向图)邻接多重表(无向图) 图的...

  • 两种方式建立图 邻接矩阵 邻接表

  • 图的遍历

    1.采用深度优先搜索(DFS)遍历图 邻接矩阵: 邻接表: 2.采用广度优先搜索(BFS)遍历图 邻接矩阵: 邻接...

  • 第七章 图

    邻接表定义 邻接表求各点入度 邻接表各点出度 DFS与BFS遍历 已知一个无向图G的邻接表存储表示如下,试写出从顶...

  • 5 图的复习目录

    5.1 图 5.2 图的存储结构 邻接矩阵 邻接表 十字链表 邻接多重链表 5.3 图的遍历 深度优先 广...

  • 六、图

    1.图的基本概念、名词术语; 2.图的邻接矩阵存储方法和邻接表(含逆邻接表)存储方法的构造原理及特点; 邻接矩阵存...

  • 从0开始——图

    1图的概念 2.图的存储结构 1.邻接矩阵 2.邻接表 3.图的遍历 1.2邻接表的深度优先算法 1.3扩展:马踏...

  • 图存存储 邻接矩阵 无向图会比较浪费空间稀疏图也会 邻接表存储 逆邻接表存储 深度和广度优先搜索 广度优先搜索

网友评论

      本文标题:图(邻接表)

      本文链接:https://www.haomeiwen.com/subject/jhwnbftx.html