泛洪算法(Flood fill)

基于图的性质:

1.四领域(上、下、左、右(递归))染色

void floodFill4(vector<vector<int>>& screen,int x,int y,int newColor,int oldColor){
	int m = screen.size();//m代表行 
	int n = screen[0].size();//n代表列  
	if(x >= 0 && x < n && y>=0 && y < m && screen[y][x] == oldColor && screen[y][x] != newColor){//判断(越界、是否需要改色情况) 
		screen[y][x] = newColor;//[y][x]等于新元素 
		floodFill4(screen,x+1,y,newColor,oldColor);//函数调用[y][x]的右边 
		floodFill4(screen,x-1,y,newColor,oldColor);//函数调用[y][x]的左边 
		floodFill4(screen,x,y+1,newColor,oldColor);//函数调用[y][x]的下边 
		floodFill4(screen,x,y-1,newColor,oldColor);//函数调用[y][x]的上边 
	}
}
vo

2.八领域(上、下、左、右、左上、左下、右上、右下(递归))染色

void floodFill8(vector<vector<int>> & screen,int x,int y,int newColor,int oldColor){
	int h = screen.size();//h代表行 
	int w = screen[0].size();//w代表列 
	if(x >= 0 && x < w && y >= 0 && y < h && screen[y][x] == oldColor && screen[y][x] != newColor){//判断(越界、是否需要改色情况) 
		screen[y][x] = newColor;//染色 
		floodFill8(screen,x+1,y,newColor,oldColor);//右染色 
		floodFill8(screen,x-1,y,newColor,oldColor);//左染色 
				floodFill8(screen,x,y+1,newColor,oldColor);//下	染色 
				floodFill8(screen,x,y-1,newColor,oldColor);//上染色 
				floodFill8(screen,x+1,y+1,newColor,oldColor);//右下染色 
				floodFill8(screen,x+1,y-1,newColor,oldColor);//右上染色 
				floodFill8(screen,x-1,y+1,newColor,oldColor);//左下染色 
				floodFill8(screen,x-1,y-1,newColor,oldColor);//左上染色 
	}
}

3.扫描线(先扫描一行或者一列内的连通像素,然后再上下行或者左右列扫描)染色

void floodFillScanline(int x,int y,int newColor,int oldColor,vector<vector<int>>& screen,int w,int h) {
	if(newColor == oldColor) return ;
	if(screen[y][x] != oldColor) return ;
	int x1=x;
	/*1*/while (x1 < w && screen[y][x1] == oldColor){
		screen[y][x1] = newColor;
		x1++;
	} 
	x1 = x - 1;
	/*2*/while (x1 >= 0 && screen[y][x1] == oldColor){
		screen[y][x1] = newColor;
		x1--;
	} 	
	x1 = x;
	/*3*/while (x1 < w && screen[y][x1] == newColor){
		if(y < h - 1 && screen[y + 1][x1] == oldColor)
			floodFillScanline(x1,y+1,newColor,oldColor,screen,w,h);
		x1++;
	} 
	x1 = x - 1;
	/*4*/while(x1 >= 0 && screen[y][x1] == newColor){
		if(y < h - 1 && screen[y+1][x1] == oldColor)
			floodFillScanline(x1,y+1,newColor,oldColor,screen,w,h);
		x1--;
	}
		x1 = x;
	/*5*/while (x1 < w && screen[y][x1] == newColor){
		if(y > 0 && screen[y - 1][x1] == oldColor)
			floodFillScanline(x1,y-1,newColor,oldColor,screen,w,h);
		x1++;
	} 
	x1 = x - 1;
	/*6*/while(x1 >= 0 && screen[y][x1] == newColor){
		if(y > 0 && screen[y - 1][x1] == oldColor)
			floodFillScanline(x1,y-1,newColor,oldColor,screen,w,h);
		x1--;
	}
}

源代码:

1.

#include<bits/stdc++.h>
using namespace std;
void floodFill4(vector<vector<int>>& screen,int x,int y,int newColor,int oldColor){
	int m = screen.size();//m代表行 
	int n = screen[0].size();//n代表列  
	if(x >= 0 && x < n && y>=0 && y < m && screen[y][x] == oldColor && screen[y][x] != newColor){//判断(越界、是否需要改色情况) 
		screen[y][x] = newColor;//[y][x]等于新元素 
		floodFill4(screen,x+1,y,newColor,oldColor);//函数调用[y][x]的右边 
		floodFill4(screen,x-1,y,newColor,oldColor);//函数调用[y][x]的左边 
		floodFill4(screen,x,y+1,newColor,oldColor);//函数调用[y][x]的下边 
		floodFill4(screen,x,y-1,newColor,oldColor);//函数调用[y][x]的上边 
	}
}
void printScreen(const vector<vector<int>>& screen){
	for(int i=0;i< screen.size();i++){
		for(int j=0;j<screen[i].size();j++){
			cout<<screen[i][j]<<" ";
		}
		cout<<endl;
	}
}
int main(){
	vector<vector<int>> screen = {
	{1,1,1,1},
	{1,1,0,1},
	{1,0,1,1}
	};
	int x=1;
	int y=1;
	int newColor =2;
	int oldColor = screen[y][x];
	cout<<"屏幕:\n";
	printScreen(screen);
	floodFill4(screen,x,y,newColor,oldColor);
	cout<<"\n屏幕2:\n";
	printScreen(screen);
}

2.

#include<bits/stdc++.h>
using namespace std;
void floodFill8(vector<vector<int>> & screen,int x,int y,int newColor,int oldColor){
	int h = screen.size();//h代表行 
	int w = screen[0].size();//w代表列 
	if(x >= 0 && x < w && y >= 0 && y < h && screen[y][x] == oldColor && screen[y][x] != newColor){//判断(越界、是否需要改色情况) 
		screen[y][x] = newColor;//染色 
		floodFill8(screen,x+1,y,newColor,oldColor);//右染色 
		floodFill8(screen,x-1,y,newColor,oldColor);//左染色 
				floodFill8(screen,x,y+1,newColor,oldColor);//下	染色 
				floodFill8(screen,x,y-1,newColor,oldColor);//上染色 
				floodFill8(screen,x+1,y+1,newColor,oldColor);//右下染色 
				floodFill8(screen,x+1,y-1,newColor,oldColor);//右上染色 
				floodFill8(screen,x-1,y+1,newColor,oldColor);//左下染色 
				floodFill8(screen,x-1,y-1,newColor,oldColor);//左上染色 
	}
}
void printScreen(const vector<vector<int>>& screen){
	for(int i=0;i< screen.size();i++){
		for(int j=0;j<screen[i].size();j++){
			cout<<screen[i][j]<<" ";
		}
		cout<<endl;
	}
}
int main(){
	vector<vector<int>> screenBuffer = {
	{1,1,1,1},
	{1,1,0,1},
	{1,0,1,1}
	};
	int x = 1;
	int y = 1;
	cout<<"1:"<<endl;
	printScreen(screenBuffer);
	floodFill8(screenBuffer,x,y,2,1);
	cout<<"2:"<<endl;
	printScreen(screenBuffer);	
}

3.

#include<bits/stdc++.h>
using namespace std;
void floodFillScanline(int x,int y,int newColor,int oldColor,vector<vector<int>>& screen,int w,int h) {
	if(newColor == oldColor) /*判断:新颜色=旧颜色(无意义)*/return ;//退出 
	if(screen[y][x] != oldColor)/*判断:sreceen[y][x]!=旧颜色(无意义)*/ return ;//退出 
	int x1=x;//创建x1=x(临时变量) 
	/*1*/while (x1 < w && screen[y][x1] == oldColor){//循环:如果没有到底、没有染色,会一直循环 
		screen[y][x1] = newColor;//染色 
		x1++;//向下移动 
	} 
	x1 = x - 1;//x1=x-1 
	/*2*/while (x1 >= 0 && screen[y][x1] == oldColor){//循环:如果没有到顶、没有染色,会一直循环
		screen[y][x1] = newColor;//染色 
		x1--;//向上移动 
	} 	
	x1 = x;//x1=x 
	/*3*/while (x1 < w && screen[y][x1] == newColor){//循环:寻找新的节点 
		if(y < h - 1 && screen[y + 1][x1] == oldColor)//判断:是不是新的节点继续染色 
			floodFillScanline(x1,y+1,newColor,oldColor,screen,w,h);//调用函数 
		x1++;//向下移动 
	} 
	x1 = x - 1;//x1=x-1
	/*4*/while(x1 >= 0 && screen[y][x1] == newColor){//循环:寻找新的节点 
		if(y < h - 1 && screen[y+1][x1] == oldColor)//判断:是不是新的节点 
			floodFillScanline(x1,y+1,newColor,oldColor,screen,w,h);//调用函数继续染色 
		x1--;//向上移动
	}
		x1 = x;//x1=x 
	/*5*/while (x1 < w && screen[y][x1] == newColor){//循环:寻找新的节点
		if(y > 0 && screen[y - 1][x1] == oldColor)//判断:是不是新的节点 
			floodFillScanline(x1,y-1,newColor,oldColor,screen,w,h);//调用函数继续染色 
		x1++;//向下移动 
	} 
	x1 = x - 1;//x1=x-1
	/*6*/while(x1 >= 0 && screen[y][x1] == newColor){//循环:寻找新的节点
		if(y > 0 && screen[y - 1][x1] == oldColor)//判断:是不是新的节点 
			floodFillScanline(x1,y-1,newColor,oldColor,screen,w,h);//调用函数继续染色 
		x1--;//向上移动
	}
}
void printScreen(const vector<vector<int>>& screen){
	for(int i=0;i< screen.size();i++){
		for(int j = 0;j < screen[i].size();j++){
			cout<<screen[i][j]<<" ";
		}
		cout<<endl;
	}
}
int main(){
	vector<vector<int>> screen = {
	{1,1,1,1},
	{1,1,0,1},
	{1,0,1,1}
	};
	int x = 2;
	int y = 2;
	int newColor = 2;
	int oldColor = screen[y][x];
	int w = screen[0].size();
	int h = screen.size();
	cout<<"1:\n";
	printScreen(screen);
	floodFillScanline(x,y,newColor,oldColor,screen,w,h);
	cout<<"2:\n";
	printScreen(screen);
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值