数据结构 六.图

六 图

6.1 图的定义和基本术语(2 个知识点):

  1. 图的定义:在计算机科学中,图是由节点(顶点)和连接节点的边组成的一种数据结构。图可以用于表示不同对象之间的关系,如网络中的计算机节点、社交网络中的用户等。

  2. 基本术语:

    • 节点(顶点):图中的元素,可以表示实体或抽象概念,如城市、人物等。节点也可以包含附加信息。
    • 边:节点之间的连接,用于表示节点之间的关系。边可以是有向的(箭头指向特定方向)或无向的(没有方向)。
    • 权重:边可以带有与其相关联的权重,用于表示节点之间的某种度量或关联程度。例如,在地图中,权重可以表示城市之间的距离或行驶时间。
    • 路径:节点序列,沿着图的边从一个节点到另一个节点。
    • 路径长度:路径中边的数量,表示从一个节点到另一个节点的步数。
    • 环:起始节点和结束节点相同的路径,形成一个循环。
    • 邻接节点:与给定节点通过一条边直接相连的节点。
    • 入度和出度:有向图中,节点的入度表示指向该节点的边的数量,出度表示从该节点发出的边的数量。

6.2 图的存储结构:

图可以使用多种方式进行存储,其中常见的有以下几种存储结构:

  • 邻接矩阵:使用二维数组表示图的连接关系,矩阵的行和列分别表示图的节点,矩阵元素表示节点之间的边。邻接矩阵在表示稠密图时效果较好,但对于稀疏图会造成空间浪费。
  • 邻接表:使用链表或数组的方式表示图的连接关系。每个节点都维护一个邻接列表,列表中包含与该节点直接相连的其他节点。邻接表适用于表示稀疏图,可以有效地节省空间。
  • 关联矩阵:使用二维数组表示图的节点和边之间的关联关系,矩阵的行表示节点,列表示边,矩阵元素表示节点是否与边相连。关联矩阵适用于需要表示节点和边的关联关系的场景。

6.3 图的遍历:

图的遍历是指从图中的某个起始节点出发,按照一定的规则访问图中的所有

节点。常用的两种图遍历算法是深度优先搜索(DFS)和广度优先搜索(BFS):

  • 深度优先搜索(DFS):从起始节点出发,沿着一条路径尽可能深入图中,直到无法继续深入为止,然后回溯到前一节点,继续探索其他路径。DFS使用栈来存储待访问节点,可以使用递归或迭代实现。
  • 广度优先搜索(BFS):从起始节点出发,首先访问起始节点的所有邻接节点,然后访问邻接节点的邻接节点,依次类推,直到访问完图中所有可达节点。BFS使用队列来存储待访问节点,保证按照节点的距离从近到远的顺序进行访问。

6.4 图的应用:

图在计算机科学和现实生活中有广泛的应用,一些常见的应用包括:

  • 社交网络分析:图可用于表示社交网络中的用户和他们之间的关系,用于分析社交网络的结构、发现社区等。
  • 网络路由:图可用于表示网络拓扑,用于选择最佳路径进行数据包的传输和路由。
  • 推荐系统:图可用于构建用户之间的关系图,用于推荐相关的内容或用户。
  • 搜索引擎:图可用于构建网页之间的链接关系,用于网页排名和搜索结果的生成。
  • 图像处理:图可用于表示图像中的像素之间的关系,用于图像分割、目标识别等。
  • 地图导航:图可用于表示地图中的道路网络,用于路径规划和导航。

6.5 图的操作:

图的操作包括以下几个常见的操作:

  1. 创建图:创建一个空的图数据结构,为图的节点和边分配内存空间。

示例(C语言):

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

#define MAX_NODES 100

// 图的结构体定义
typedef struct {
    int vertices[MAX_NODES][MAX_NODES]; // 邻接矩阵存储图的连接关系
    int numNodes; // 图中节点的数量
} Graph;

// 创建图
Graph* createGraph(int numNodes) {
    Graph* graph = (Graph*)malloc(sizeof(Graph));
    graph->numNodes = numNodes;

    // 初始化邻接矩阵
    for (int i = 0; i < numNodes; i++) {
        for (int j = 0; j < numNodes; j++) {
            graph->vertices[i][j] = 0;
        }
    }

    return graph;
}

int main() {
    int numNodes = 5;
    Graph* graph = createGraph(numNodes);

    // 执行其他图操作...

    free(graph);
    return 0;
}
  1. 添加节点:向图中添加一个新的节点。

示例(C语言):

// 添加节点
void addNode(Graph* graph) {
    if (graph->numNodes >= MAX_NODES) {
        printf("Maximum number of nodes reached.\n");
        return;
    }

    // 在邻接矩阵中增加一行和一列
    for (int i = 0; i <= graph->numNodes; i++) {
        graph->vertices[i][graph->numNodes] = 0;
        graph->vertices[graph->numNodes][i] = 0;
    }

    graph->numNodes++;
}

int main() {
    Graph* graph = createGraph(3);

    addNode(graph); // 添加一个节点

    // 执行其他图操作...

    free(graph);
    return 0;
}
  1. 添加边:在两个节点之间添加一条边。

示例(C语言):

// 添加边
void addEdge(Graph* graph, int node1, int node2) {
    if (node1 < 0 || node1 >= graph->numNodes || node2 < 0 || node2 >= graph->numNodes) {
        printf("Invalid node index.\n");
        return;
    }

    // 在邻接矩阵中设置边的连接关系
    graph->vertices[node1][node2] = 1;
    graph->vertices[node2][node1] = 1;
}

int main() {
    Graph* graph = createGraph(4);

    addEdge(graph, 0, 1); // 添加一条边连接节点0和节点1

    // 执行其他图操作...

    free(graph);
    return 0;
}
  1. 删除节点:从图中删除一个节点以及与其相关的边。

示例(C语言):

// 删除节点
void removeNode(Graph* graph, int node) {
    if (node < 0 || node >= graph->numNodes) {
        printf("Invalid node index.\n");
        return;
    }

    // 从邻接矩阵中删除该节点的行和列
    for (int i = node; i < graph->

numNodes - 1; i++) {
        for (int j = 0; j < graph->numNodes; j++) {
            graph->vertices[i][j] = graph->vertices[i + 1][j];
            graph->vertices[j][i] = graph->vertices[j][i + 1];
        }
    }

    // 将最后一行和最后一列置为0
    for (int i = 0; i < graph->numNodes; i++) {
        graph->vertices[graph->numNodes - 1][i] = 0;
        graph->vertices[i][graph->numNodes - 1] = 0;
    }

    graph->numNodes--;
}

int main() {
    Graph* graph = createGraph(4);

    removeNode(graph, 2); // 删除节点2及其相关的边

    // 执行其他图操作...

    free(graph);
    return 0;
}
  1. 删除边:从图中删除两个节点之间的边。

示例(C语言):

// 删除边
void removeEdge(Graph* graph, int node1, int node2) {
    if (node1 < 0 || node1 >= graph->numNodes || node2 < 0 || node2 >= graph->numNodes) {
        printf("Invalid node index.\n");
        return;
    }

    // 在邻接矩阵中取消边的连接关系
    graph->vertices[node1][node2] = 0;
    graph->vertices[node2][node1] = 0;
}

int main() {
    Graph* graph = createGraph(4);

    removeEdge(graph, 1, 2); // 删除节点1和节点2之间的边

    // 执行其他图操作...

    free(graph);
    return 0;
}

这些示例演示了在C语言中执行图的基本操作的方法。请注意,这些示例中的图表示使用邻接矩阵来存储连接关系,你可以根据需要选择其他图的存储结构来实现相应的操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值