实现邻接表的图结构

        在计算机科学中,图是一种重要的抽象数据结构,广泛应用于各种领域,如社交网络分析、路由算法等。图通常包含若干个顶点(Vertex)和连接顶点的(Edge)。有两种常见的图的表示方式:邻接矩阵和邻接表。本文主要讲解如何通过邻接表来表示一个图。

#include <stdio.h> 
#include <stdlib.h>

#define MaxVertex 5  // 图的最大顶点数
typedef char E;    // 定义元素类型为字符

// 头节点结构体,存储顶点的元素和指向下一个节点的指针
struct HeadNode {
    E element;            // 顶点元素
    struct Node *next;    // 指向下一个节点的指针
};

// 节点结构体,存储指向下一个节点的指针和邻接的顶点
typedef struct Node {
    int nextVertex;      // 存储邻接顶点的索引
    struct Node *next;   // 指向下一个节点的指针
} *Node;

// 邻接表结构体,包含顶点数量、边数量和顶点数组
typedef struct AdjacencyGraph {
    int vertexCount;     // 顶点数量
    int edgeCount;       // 边的数量
    struct HeadNode vertex[MaxVertex];  // 存储每个顶点的头节点
} *Graph;

// 初始化邻接表,创建一个空图
Graph create() {
    Graph graph = malloc(sizeof(struct AdjacencyGraph));  // 分配内存
    graph->vertexCount = graph->edgeCount = 0;            // 顶点和边的初始数量为0
    return graph;                                         // 返回图的指针
}

// 向图中添加顶点
void addVertex(Graph graph, E e) {
    graph->vertex[graph->vertexCount].element = e;  // 将元素e添加到vertex数组的当前索引位置
    graph->vertex[graph->vertexCount].next = NULL;  // 当前顶点的下一个节点为空
    graph->vertexCount++;                           // 顶点数量增加
}

// 向图中添加边,连接顶点a和顶点b
void addEdge(Graph graph, int a, int b) {
    Node node = graph->vertex[a].next;  // 获取顶点a的下一个节点
    Node newnode = malloc(sizeof(struct Node));  // 创建一个新的节点
    newnode->next = NULL;                         // 新节点的next指针为空
    newnode->nextVertex = b;                     // 新节点存储的邻接顶点是b

    if (!node) {  // 如果a没有邻接顶点
        graph->vertex[a].next = newnode;  // 将b直接添加为a的邻接顶点
    } else {  // 如果a已经有邻接顶点
        do {
            if (node->nextVertex == b) return;  // 如果b已经是a的邻接顶点,则不重复添加
            if (node->next) node = node->next;  // 否则遍历下一个节点
            else break;
        } while (1);
        node->next = newnode;  // 将新节点插入到a的邻接顶点链表中
    }

    graph->edgeCount++;  // 边的数量增加
}

// 打印图的邻接表
void printGraph(Graph graph) {
    for (int i = 0; i < graph->vertexCount; i++) {  // 遍历所有顶点
        printf("%d | %c", i, graph->vertex[i].element);  // 打印顶点的索引和元素
        Node node = graph->vertex[i].next;  // 获取当前顶点的第一个邻接节点
        while (node) {  // 如果当前顶点有邻接节点
            printf(" -> %d", node->nextVertex);  // 打印当前节点的邻接顶点
            node = node->next;  // 移动到下一个邻接节点
        }
        printf("\n");
    }
}

// 主函数
int main(void) {
    Graph graph = create();  // 创建图

    // 添加顶点A到D
    for (int c = 'A'; c <= 'D'; ++c)
        addVertex(graph, (char)c);  // 将字符A到D添加为顶点

    // 添加边
    addEdge(graph, 0, 1);   // A -> B
    addEdge(graph, 1, 2);   // B -> C
    addEdge(graph, 2, 3);   // C -> D
    addEdge(graph, 3, 0);   // D -> A
    addEdge(graph, 2, 0);   // C -> A

    printGraph(graph);  // 打印邻接表
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值