C语言实现图的搜索算法示例

C语言实现图的搜索算法示例

在C语言中,我们可以使用邻接矩阵或邻接表来表示图,实现图的搜索算法,本篇文章将详细介绍如何使用C语言实现图的搜索算法,以及提供两个示例说明。

邻接矩阵表示图

邻接矩阵是使用二维数组表示图的一种方法,其中数组的每个元素代表图中的一个节点,如果两个节点之间存在边,则数组元素的值为1,否则为0。例如,下面是一个由邻接矩阵表示的无向图。

    0  1  2  3
0   0  1  1  0
1   1  0  1  1
2   1  1  0  1
3   0  1  1  0

在C语言中,我们可以使用二维数组来表示邻接矩阵,如下所示:

#define MAX_NODE 4
int graph[MAX_NODE][MAX_NODE] = {
    {0, 1, 1, 0},
    {1, 0, 1, 1},
    {1, 1, 0, 1},
    {0, 1, 1, 0}
};

深度优先搜索

深度优先搜索(DFS)是一种用于图遍历或树遍历的算法,其思路类似于前序遍历二叉树。DFS首先访问起始节点,然后访问与起始节点相连的第一个节点,再递归地访问这个节点的所有相邻节点。深度优先搜索一直进行到遇到一个没有未访问的相邻节点的节点,然后返回到前一个节点,继续访问未访问的相邻节点,直到所有节点都被访问。下面是一个使用邻接矩阵实现DFS的示例代码。

int visited[MAX_NODE] = {0};
void dfs(int node) {
    visited[node] = 1;
    printf("%d ", node);
    for (int i = 0; i < MAX_NODE; i++) {
        if (graph[node][i] == 1 && visited[i] == 0) {
            dfs(i);
        }
    }
}

广度优先搜索

广度优先搜索(BFS)是一种用于图遍历或树遍历的算法,其思路类似于层序遍历二叉树。BFS首先访问起始节点,然后访问起始节点的所有相邻节点,再递归地访问相邻节点的相邻节点。我们使用一个队列来存储要访问的节点。BFS在遍历到一个节点时,将该节点的所有相邻节点加入队列中,然后访问队列的第一个节点,并将其出队。下面是一个使用邻接矩阵实现BFS的示例代码。

void bfs(int node) {
    int queue[MAX_NODE];
    int front = -1, rear = -1;
    visited[node] = 1;
    queue[++rear] = node;
    while (front < rear) {
        int temp = queue[++front];
        printf("%d ", temp);
        for (int i = 0; i < MAX_NODE; i++) {
            if (graph[temp][i] == 1 && visited[i] == 0) {
                visited[i] = 1;
                queue[++rear] = i;
            }
        }
    }
}

示例1:使用邻接矩阵表示二分图

在算法设计中,常常用到二分图,其中每个节点被分为左右两部分,左部分的节点只与右部分的节点相连,右部分的节点只与左部分的节点相连。下面是一个由邻接矩阵表示的二分图。

    0  1  2  3  4
0   0  1  0  1  0
1   1  0  1  0  1
2   0  1  0  1  0
3   1  0  1  0  1
4   0  1  0  1  0

我们可以使用DFS或BFS遍历这个图,代码类似于上面的示例代码。

示例2:使用邻接矩阵表示迷宫的搜索

我们可以使用邻接矩阵来表示迷宫,其中每个元素表示一个迷宫格子,值为1表示这个格子是墙,不能通过,值为0表示这个格子是路,可以通过。我们可以用DFS或BFS来搜索迷宫中的通路。下面是一个由邻接矩阵表示的简单迷宫。

    0  1  2  3
0   1  1  1  1
1   1  0  0  1
2   1  1  0  1
3   1  1  1  1

在这个例子中,我们可以使用BFS来搜索迷宫中的通路,如果起点和终点可以通过路相连,则输出通路。下面是一个简单的BFS实现。

void bfs_maze(int sx, int sy, int tx, int ty) {
    int q[MAX_NODE * MAX_NODE];
    int front = -1, rear = -1;
    q[++rear] = sx * MAX_NODE + sy;
    visited[sx][sy] = 1;
    while (front < rear) {
        int temp = q[++front];
        int x = temp / MAX_NODE, y = temp % MAX_NODE;
        if (x == tx && y == ty) {
            printf("[");
            while (pre[x][y] != -1) {
                printf("(%d,%d)", x, y);
                int t = pre[x][y];
                x = t / MAX_NODE, y = t % MAX_NODE;
            }
            printf("(%d,%d)]", sx, sy);
            return;
        }
        for (int i = 0; i < 4; i++) {
            int nx = x + dx[i], ny = y + dy[i];
            if (nx >= 0 && nx < MAX_NODE && ny >= 0 && ny < MAX_NODE
                && graph[nx][ny] == 0 && visited[nx][ny] == 0) {
                visited[nx][ny] = 1;
                pre[nx][ny] = x * MAX_NODE + y;
                q[++rear] = nx * MAX_NODE + ny;
            }
        }
    }
}

上面的代码中,我们使用二维数组pre来记录BFS访问过程中所有被访问节点的前驱节点。在遇到终点时,从pre数组中可以逆向找到从起点到终点的路径。

总之,使用邻接矩阵表示图可以方便地实现图的搜索算法,我们可以将搜索算法应用于各种类型的问题中。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:C语言实现图的搜索算法示例 - Python技术站

(0)
上一篇 2023年5月23日
下一篇 2023年5月23日

相关文章

  • C语言文件操作零基础新手入门保姆级教程

    C语言文件操作零基础新手入门保姆级教程 文件操作概述 文件操作是指对文件进行读写、复制、移动、重命名等操作的过程。C语言中提供了丰富的文件操作函数,使得开发者可以轻松地实现文件的操作。 C语言文件操作的基本流程为: 打开文件 进行读/写操作 关闭文件 文件操作函数 打开文件 fopen()函数用于打开文件,函数定义如下: FILE *fopen(const …

    C 2023年5月23日
    00
  • Go 使用Unmarshal将json赋给struct出错的原因及解决

    问题描述 在使用Go语言的Unmarshal函数将json数据赋给struct时,可能会遇到一些出错的情况。 下面是一个例子: package main import ( "encoding/json" "fmt" ) type Person struct { Name string Age int } func ma…

    C 2023年5月23日
    00
  • C++内核对象封装单实例启动程序的类

    针对这个话题,我来给你详细讲解一下。 什么是C++内核对象封装单实例启动程序的类 C++内核对象封装单实例启动程序的类,是一种用C++编写的程序类,可以确保只有一个实例被启动运行,防止多次启动同一程序时造成的冲突和不必要的资源浪费。该类通常会使用操作系统的内核对象来进行进程管理和控制,保证只有一个实例在运行。 如何实现C++内核对象封装单实例启动程序的类 下…

    C 2023年5月22日
    00
  • C++文件读写操作详解

    先简单介绍一下C++中文件读写操作的基本概念: C++文件读写操作是指在C++程序中对计算机中的文件进行输入和输出的操作。文件读写操作是必不可少的C++编程操作之一,在文件读写操作中我们需要用到文件指针,读写位置指针,并且需要了解文件的打开、关闭、读写、复制等基本操作。C++文件操作通常使用C++标准库中的fstream头文件实现。下面介绍一些基本操作和示例…

    C 2023年5月22日
    00
  • Basic求10000以内的完美数

    下面是 “Basic求10000以内的完美数” 的完整攻略: 任务描述 在Basic语言中,编写代码搜索10000以内的所有完美数并输出。 任务分析 完美数是指一个数等于其自身所有因子(不包括自己)之和,例如:6就是完美数,它的因子为1、2、3,而1 + 2 + 3正好等于6。因此,我们可以采用以下方法来寻找10000以内的完美数: 遍历1~10000之间的…

    C 2023年5月22日
    00
  • C++ Boost Atomic详细讲解

    C++ Boost Atomic详细讲解 什么是Boost Atomic? Boost Atomic是C++ Boost库的一个组件,提供了跨平台多线程编程中的原子操作。原子操作是一种不可分割的操作,要么全部完成,要么全部不完成。 如何使用Boost Atomic? 安装Boost库 要想使用Boost Atomic,需要先安装Boost库。可以参考Boos…

    C 2023年5月23日
    00
  • C语言中如何实现桶排序

    C语言中实现桶排序,其主要思想是将待排序的序列分解成若干个区间,对于每个区间分别使用一个桶来存放该区间内的元素,然后对每个桶中的元素进行排序,最后按照桶的顺序将所有元素连接起来,就得到了排好序的序列。 具体的实现步骤如下: 1.确定桶的数量和区间范围。根据序列中的元素取值范围,确定桶的数量并计算区间大小。 2.将元素分配到对应的桶中。遍历待排序的序列,将每个…

    C 2023年5月22日
    00
  • TPLINK TLR5408PE-AC一体VPN路由器怎么样? tpr5408pe测评

    TPLINK TLR5408PE-AC一体VPN路由器怎么样? 简介 TPLINK TLR5408PE-AC是一款集成了VPN功能的路由器。它支持IEEE802.11ac无线网络标准,最高可达1300Mbps,同时支持IPv4和IPv6协议,提供了4个Gigabit以太网口和2个USB接口。另外,它还支持PPTP、L2TP、IPSec和SSL VPN等多种安…

    C 2023年5月23日
    00
合作推广
合作推广
分享本页
返回顶部