图论可达性c语言实现

简介: 这篇文章详细解释了图论中可达性的概念,并提供了无向图和有向图的C语言实现代码,包括图的初始化、边的添加、深度优先搜索(DFS)以及可达性的检查。

概述

图论中的可达性是指在图中是否存在从一个顶点到另一个顶点的路径。这是图论中的一个基本概念,对于许多实际问题的建模和解决都非常重要。以下是关于图论可达性的一些重要概念和信息:

  1. 有向图和无向图: 图可以分为有向图和无向图。在有向图中,边有方向,从一个顶点到另一个顶点的路径是有向的。在无向图中,边没有方向,路径是无向的。

  2. 可达性定义: 在有向图中,从顶点A到顶点B的可达性表示存在一条有向路径从A到B。在无向图中,如果存在一条路径从顶点A到顶点B,那么A和B被认为是可达的。

  3. 深度优先搜索(DFS): DFS是一种用于遍历图的算法,可以用来检查可达性。通过从起始顶点开始,尽可能深入图中,直到无法继续为止。DFS可以用来查找路径并判断两个顶点之间是否可达。

  4. 广度优先搜索(BFS): BFS是另一种遍历图的算法,它从起始顶点开始,逐层遍历图。BFS也可以用于检查可达性,并找到最短路径。

  5. 图的表示: 图可以通过邻接矩阵或邻接表等方式表示。邻接矩阵是一个二维数组,其中元素表示顶点之间的连接关系。邻接表是一种更灵活的表示方法,使用链表来表示每个顶点的邻接顶点。

  6. 应用: 可达性在许多领域都有重要应用,如网络路由、社交网络分析、数据库查询优化等。在计算机科学和工程中,图的可达性是解决许多实际问题的关键步骤。

总的来说,图论中的可达性是一个关键的概念,它帮助我们理解图结构中的路径和连接关系,为解决各种问题提供了强大的工具。

以下是无向图的可达性实现代码。

无向图完整代码

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

#define MAX_VERTICES 100

// 定义图的结构
struct Graph {
    int vertices;          // 图的顶点数
    int adjacencyMatrix[MAX_VERTICES][MAX_VERTICES];  // 邻接矩阵表示图的连接关系
};

// 函数声明
void initGraph(struct Graph* graph, int vertices);
void addEdge(struct Graph* graph, int start, int end);
void DFS(struct Graph* graph, int vertex, int visited[MAX_VERTICES]);
void checkReachability(struct Graph* graph, int start, int end);

int main() {
    struct Graph graph;
    int vertices, edges, start, end;

    // 输入图的顶点数和边数
    printf("输入图的顶点数和边数:");
    scanf("%d %d", &vertices, &edges);

    initGraph(&graph, vertices);

    // 输入图的边
    printf("输入图的边(每行包含两个顶点,表示一条边):\n");
    for (int i = 0; i < edges; i++) {
        int startVertex, endVertex;
        scanf("%d %d", &startVertex, &endVertex);
        addEdge(&graph, startVertex, endVertex);
    }

    // 输入要检查可达性的起始点和结束点
    printf("输入要检查可达性的起始点和结束点:");
    scanf("%d %d", &start, &end);

    // 检查可达性
    checkReachability(&graph, start, end);

    return 0;
}

// 初始化图
void initGraph(struct Graph* graph, int vertices) {
    graph->vertices = vertices;

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

// 添加边
void addEdge(struct Graph* graph, int start, int end) {
    // 有向图,将起始点到结束点的边标记为1
    graph->adjacencyMatrix[start][end] = 1;
}

// 深度优先搜索
void DFS(struct Graph* graph, int vertex, int visited[MAX_VERTICES]) {
    visited[vertex] = 1;
    printf("%d ", vertex);

    for (int i = 0; i < graph->vertices; i++) {
        if (graph->adjacencyMatrix[vertex][i] == 1 && !visited[i]) {
            DFS(graph, i, visited);
        }
    }
}

// 检查可达性
void checkReachability(struct Graph* graph, int start, int end) {
    int visited[MAX_VERTICES] = {0};

    printf("从顶点 %d 出发,DFS 遍历结果为:", start);
    DFS(graph, start, visited);

    if (visited[end]) {
        printf("\n%d 可达 %d\n", start, end);
    } else {
        printf("\n%d 不可达 %d\n", start, end);
    }
}

测试无向图

有向图完整代码

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

#define MAX_VERTICES 100

// 定义图的结构
struct Graph {
    int vertices;          // 图的顶点数
    int adjacencyMatrix[MAX_VERTICES][MAX_VERTICES];  // 邻接矩阵表示图的连接关系
};

// 函数声明
void initGraph(struct Graph* graph, int vertices);
void addEdge(struct Graph* graph, int start, int end);
void DFS(struct Graph* graph, int vertex, int visited[MAX_VERTICES]);
void checkReachability(struct Graph* graph, int start, int end);

int main() {
    struct Graph graph;
    int vertices, edges, start, end;

    // 输入图的顶点数和边数
    printf("输入图的顶点数和边数:");
    scanf("%d %d", &vertices, &edges);

    initGraph(&graph, vertices);

    // 输入图的边
    printf("输入图的边(每行包含两个顶点,表示一条边):\n");
    for (int i = 0; i < edges; i++) {
        int startVertex, endVertex;
        scanf("%d %d", &startVertex, &endVertex);
        addEdge(&graph, startVertex, endVertex);
    }

    // 输入要检查可达性的起始点和结束点
    printf("输入要检查可达性的起始点和结束点:");
    scanf("%d %d", &start, &end);

    // 检查可达性
    checkReachability(&graph, start, end);

    return 0;
}

// 初始化图
void initGraph(struct Graph* graph, int vertices) {
    graph->vertices = vertices;

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

// 添加边
void addEdge(struct Graph* graph, int start, int end) {
    // 有向图,将起始点到结束点的边标记为1
    graph->adjacencyMatrix[start][end] = 1;
}

// 深度优先搜索
void DFS(struct Graph* graph, int vertex, int visited[MAX_VERTICES]) {
    visited[vertex] = 1;
    printf("%d ", vertex);

    for (int i = 0; i < graph->vertices; i++) {
        if (graph->adjacencyMatrix[vertex][i] == 1 && !visited[i]) {
            DFS(graph, i, visited);
        }
    }
}

// 检查可达性
void checkReachability(struct Graph* graph, int start, int end) {
    int visited[MAX_VERTICES] = {0};

    printf("从顶点 %d 出发,DFS 遍历结果为:", start);
    DFS(graph, start, visited);

    if (visited[end]) {
        printf("\n%d 可达 %d\n", start, end);
    } else {
        printf("\n%d 不可达 %d\n", start, end);
    }
}

测试有向图

目录
相关文章
|
6月前
|
算法 搜索推荐 C语言
C语言中的经典算法实现
C语言中的经典算法实现
68 1
|
6月前
|
算法 C语言
约瑟夫环的C语言和86/88汇编非递归算法
约瑟夫环的C语言和86/88汇编非递归算法
63 0
|
C语言 C++
【C语言】8道经典指针笔试题(深度解剖)
【C语言】8道经典指针笔试题(深度解剖)
127 0
|
C语言
c语言数据结构-图的遍历
c语言数据结构-图的遍历
119 0
c语言数据结构-图的遍历
|
算法 C语言
简单算法之二分搜索——C语言
线性搜索效率低下,而二分搜索可以将数组中的数字分为两半,从而提高搜索效率。
|
存储 算法 C语言
C语言实现哈希搜索算法
哈希搜索,也叫散列查找,是一种通过哈希表(散列表)实现快速查找目标元素的算法。哈希搜索算法通常适用于需要快速查找一组数据中是否存在某个元素的场景,其时间复杂度最高为 O(1),而平均情况下的时间复杂度通常相当接近 O(1),因此在实际应用中具有很高的效率和性能。
134 0
C语言 | 数据结构—约瑟夫环问题
目录 首先什么是约瑟夫环 约瑟夫环实现方式 一、创建结构体变量 二、初始化链表 三、构建循环链表 四、删除链表 五、完整代码及注释讲解 首先什么是约瑟夫环 约瑟夫环是循环链表中的一个经典问题;题目描述:n 个人围成一圈,从第一个人开始报数,数到 m 的人出列,再由下一个人重新从 1 开始报数,数到 m 的人再出圈,依次类推,直到所有的人都出圈; 假设10个人围成一圈,依次编号1到10,按从小到大顺序报数,报到3的人出局,流程示意图如下 约瑟夫环实现方式 我个人倾向于循环链表; 一、创建结构体变量 typedef struct Node{ int data; //数据域 st
C语言 | 数据结构—约瑟夫环问题
|
机器学习/深度学习 存储 C语言
探究C语言中的二叉树
树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。
|
存储 算法 C语言
简单算法之线性搜索——C语言
线性搜索是一种最简单的搜索方案,它通过遍历数组中的每一个数据来实现目的,即找出目标数字的位置或确认该数字是否存在。在本篇文章中,我们将介绍如何使用C语言实现线性搜索算法。
|
存储 编译器 C语言
《c语言深度解剖》--一套非常经典的笔试题(2)
学习完c语言,需要对所学知识进行一个检测,下面有一套笔试题, 你有四十分钟进行检测,每道题五分,严格要求自己打分。 根据作者原话:在没有何提示的情况下,如果能得满分,那你可以扔掉本书了,因为你的水平已经大大超过了作者;如果能得80分以上,说明你的C语言基础还不错,学习本书可能会比较轻松;如果得分在50分以下,也不要气馁,努力学习就行了;如果不小心得了10分以下,那就得给自己敲敲警钟了;如果不幸得了0分,那实在是不应该,因为毕竟很多题是很简单的。