📜  查找岛屿数量的 C 程序 |设置 1(使用 DFS)(1)

📅  最后修改于: 2023-12-03 14:55:33.849000             🧑  作者: Mango

查找岛屿数量的 C 程序 | 使用 DFS

简介

岛屿数量是一道非常经典的算法问题,给定一个由 0 和 1 组成的矩阵 grid,其中 0 表示水,1 表示陆地。岛屿被水包围,被水包围的陆地是不同的岛屿。我们要求出矩阵中岛屿的数量。本文将介绍如何使用 DFS 算法来解决这个问题。

算法思路

我们可以将矩阵看作一个无向图,每个元素对应一个节点,相邻且值为 1 的节点之间存在一条边。对于每一个值为 1 的节点,我们可以使用 DFS 算法来遍历所有相邻的节点,把所有值为 1 的节点标记为已访问,并且将它们的相邻节点加入到待访问节点列表中。当所有相邻节点都已经被访问完后,我们就找到了一个岛屿。

为了防止访问重复的节点,我们需要使用一个 visited 数组来记录每个节点是否已经被访问过。我们遍历所有节点,对于值为 1 的节点,如果它没有被访问过,就从这个节点开始进行 DFS 遍历,每次发现一个新的节点,就更新 visited 数组,并将该节点的相邻节点加入到待访问节点列表中。当一个岛屿被遍历完成后,我们增加岛屿数量的计数器,并继续遍历下一个未被访问的节点,直到矩阵中的所有节点都被遍历完。

代码实现
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

void dfs(int** grid, int gridSize, int* gridColSize, int i, int j, bool** visited) {
    if (i < 0 || i >= gridSize || j < 0 || j >= gridColSize[i] || visited[i][j] || grid[i][j] == 0) {
        return;
    }

    visited[i][j] = true;
    dfs(grid, gridSize, gridColSize, i - 1, j, visited);
    dfs(grid, gridSize, gridColSize, i + 1, j, visited);
    dfs(grid, gridSize, gridColSize, i, j - 1, visited);
    dfs(grid, gridSize, gridColSize, i, j + 1, visited);
}

int numIslands(int** grid, int gridSize, int* gridColSize){
    bool** visited = (bool**)calloc(gridSize, sizeof(bool*));

    for (int i = 0; i < gridSize; i++) {
        visited[i] = (bool*)calloc(gridColSize[i], sizeof(bool));
    }

    int count = 0;

    for (int i = 0; i < gridSize; i++) {
        for (int j = 0; j < gridColSize[i]; j++) {
            if (grid[i][j] == 1 && !visited[i][j]) {
                count++;
                dfs(grid, gridSize, gridColSize, i, j, visited);
            }
        }
    }

    for (int i = 0; i < gridSize; i++) {
        free(visited[i]);
    }

    free(visited);

    return count;
}
解释说明

本程序使用了递归和动态内存分配,需要注意内存泄漏的问题,特别是在 visited 数组的分配和释放过程中。在已访问的节点(visited[i][j])和岛屿数量计数器(count)之间没有直接的关系,因此在 DFS 函数中并没有尝试进行计数器的增加,而是在每次发现新岛屿时才增加计数器的值。

参考来源