【入门级-算法-8、图论算法:泛洪算法 (Flood Fill)】

一、算法概述

1.泛洪算法(Flood Fill):图论和图像处理中的一种经典算法,用于确定连通区域。

它的典型应用是 "油漆桶"工具:点击图片中的一个像素,程序会把与该像素颜色相同且连通的区域全部填充为新颜色。

  1. 核心思想
    从种子点(起点)出发,向四周相邻位置(通常四邻域或八邻域)扩散,访问所有"连通"且"满足条件"的节点,直到所有连通区域都被访问。。

3.连通规则:

4 邻域:上、下、左、右

8 邻域:上、下、左、右 + 对角线方向

条件:通常颜色相同(或特征相似)

二、实现方法

图论模型建立

// 网格图的抽象表示

typedef struct {

int color; // 节点颜色

int visited; // 访问标记(可选)

} Node;

// 四连通邻接关系(隐式图,不需要显式存储边)

// 每个节点最多有4个邻居:上、下、左、右

const int dx4 = {-1, 1, 0, 0}; // 行方向偏移

const int dy4 = {0, 0, -1, 1}; // 列方向偏移

//递归DFS版本(最接近图论定义)

#include <stdio.h>

#include <stdlib.h>

// 四连通泛洪填充(递归DFS)

// 参数说明:

// image: 二维数组,存储颜色值

// rows, cols: 图像尺寸

// x, y: 当前坐标

// targetColor: 要填充的目标颜色

// newColor: 新颜色

void floodFillRecursive(int** image,

int rows, int cols,

int x, int y,

int targetColor,

int newColor)

{

// 1. 边界检查(防止越界)

if (x < 0 || x >= rows || y < 0 || y >= cols) {

return;

}

复制代码
// 2. 颜色匹配检查(图论中的"节点值相等")
if (image[x][y] != targetColor) {
    return;
}

// 3. 访问当前节点(染色)
image[x][y] = newColor;

// 4. 递归访问所有邻接节点(图论中的DFS遍历)
floodFillRecursive(image, rows, cols, x + 1, y, targetColor, newColor);
floodFillRecursive(image, rows, cols, x - 1, y, targetColor, newColor);
floodFillRecursive(image, rows, cols, x, y + 1, targetColor, newColor);
floodFillRecursive(image, rows, cols, x, y - 1, targetColor, newColor);

}

// 注意:递归版本在图像较大时(>1000x1000)可能导致栈溢出

测试程序

#include <stdio.h>

#include <stdlib.h>

// 创建动态二维数组

int** createImage(int rows, int cols) {

int** image = (int**)malloc(sizeof(int*) * rows);

for (int i = 0; i < rows; i++) {

imagei = (int*)malloc(sizeof(int) * cols);

}

return image;

}

// 释放内存

void freeImage(int** image, int rows) {

for (int i = 0; i < rows; i++) {

free(imagei);

}

free(image);

}

// 打印图像

void printImage(int** image, int rows, int cols) {

for (int i = 0; i < rows; i++) {

for (int j = 0; j < cols; j++) {

printf("%2d ", imageij);

}

printf("\n");

}

printf("\n");

}

// 复制图像

int** copyImage(int** src, int rows, int cols) {

int** dst = createImage(rows, cols);

for (int i = 0; i < rows; i++) {

for (int j = 0; j < cols; j++) {

dstij = srcij;

}

}

return dst;

}

int main() {

// 创建测试图像(0表示空白,1-9表示不同颜色)

int rows = 8, cols = 8;

int** original = createImage(rows, cols);

复制代码
// 初始化复杂图像(包含多个连通区域)
int init[8][8] = {
    {1, 1, 1, 2, 2, 2, 3, 3},
    {1, 0, 1, 2, 0, 2, 3, 3},
    {1, 1, 1, 2, 2, 2, 3, 3},
    {4, 4, 4, 5, 5, 5, 6, 6},
    {4, 0, 4, 5, 0, 5, 6, 6},
    {4, 4, 4, 5, 5, 5, 6, 6},
    {7, 7, 7, 8, 8, 8, 9, 9},
    {7, 0, 7, 8, 0, 8, 9, 9}
};

for (int i = 0; i < rows; i++) {
    for (int j = 0; j < cols; j++) {
        original[i][j] = init[i][j];
    }
}

printf("=== 原始图像 ===\n");
printImage(original, rows, cols);

// 测试1:递归DFS填充左上角区域(颜色1 -> 99)
int** img1 = copyImage(original, rows, cols);
printf("=== 测试1:递归DFS从(0,0)填充颜色1->99 ===\n");
floodFillRecursive(img1, rows, cols, 0, 0, 1, 99);
printImage(img1, rows, cols);
freeImage(img1, rows);

// 测试2:迭代DFS填充中间区域(颜色5 -> 55)
int** img2 = copyImage(original, rows, cols);
printf("=== 测试2:迭代DFS从(3,3)填充颜色5->55 ===\n");
floodFillIterativeDFS(img2, rows, cols, 3, 3, 5, 55);
printImage(img2, rows, cols);
freeImage(img2, rows);

freeImage(original, rows);
return 0;

}

三、经典应用场景

图像编辑器的油漆桶工具

游戏地图区域填充(扫雷翻开一片空白区)

迷宫/连通区域计数

多边形种子填充(计算机图形学)

相关推荐
Robot_Nav几秒前
MPPI 局部规划器实验设计讲解
人工智能·算法·mppi
mingo_敏28 分钟前
Mean-Teacher 均值教师自训练框架详解
算法·均值算法
星空露珠1 小时前
迷你世界UGc3.0脚本Wiki[剧情动画模块管理接口 Timeline]
开发语言·数据结构·算法·游戏·lua
笨笨没好名字1 小时前
Leetcode刷题python3版第一周(下)
linux·算法·leetcode
手写码匠1 小时前
手写 LLM 安全护栏:从内容审核到越狱防御的完整实现
人工智能·深度学习·算法·aigc
luj_17681 小时前
草酸与烟酸对消化及糖代谢的影响解析
服务器·c语言·开发语言·经验分享·算法
青风971 小时前
16-ADAPTRACK:基于自适应阈值的多目标跟踪匹配算法
人工智能·算法·目标跟踪
汤姆yu2 小时前
macOS系统下Aider完整安装、配置与实战使用教程
大数据·人工智能·算法·macos·github·copilot
Sam09272 小时前
【AI 算法精讲 14】TF-IDF:词频与逆文档频率
人工智能·python·算法·ai
AI科技星2 小时前
拓扑生命系统确定性理论:基于32维流形的遗传密码起源与衰老动力学( 中英双语顶刊终稿·标准数学符号)
开发语言·网络·人工智能·算法·机器学习·乖乖数学·全域数学