1、在《填充算法(一)》中中提到的都是最基本的递归填充算法,即由一个起始的填充点开始,向周围各个方向的点递归,根据递归条件,进而达到填充某个颜色块(注入填充) 或是 任意区域(边缘填充)的效果。但是,递归填充算法占用的栈空间太大,而且递归深度难以确定;虽然可以通过调整栈大小来解决问题,但是这样做显然并不是很好。本文考虑用其它算法替代递归算法,进而实现相同的填充效果。


2、将递归算法转化为一般的非递归算法,一般都可以通过Stack(栈)来实现,以递归的注入填充算法为例:

(1)递归注入填充算法:

void FloodSeedFill(CDC* pDC, int x, int y, COLORREF colorOld, COLORREF colorNew)
{
	if (pDC->GetPixel( CPoint(x, y) ) == colorOld)
	{
		pDC->SetPixel( CPoint(x, y), colorNew);

		FloodSeedFill(pDC, x, y - 1, colorOld, colorNew); // 上
		FloodSeedFill(pDC, x + 1, y, colorOld, colorNew); // 右
		FloodSeedFill(pDC, x, y + 1, colorOld, colorNew); // 下
		FloodSeedFill(pDC, x - 1, y, colorOld, colorNew); // 左
	}
}



(2)非递归注入填充算法(C++ STL Stack):


void FloodSeedFill(CDC* pDC, int x, int y, COLORREF colorOld, COLORREF colorNew)
{
	stack <CPoint> ptStack; //用来保存需要填充的点

	CPoint ptCurrent = CPoint(x, y);	//将种子点设为当前需要填的点
	ptStack.push( ptCurrent );			//将种子点压入堆栈中
	
	while ( !ptStack.empty() )
	{
		ptCurrent = ptStack.top();
		pDC->SetPixel( ptCurrent, colorNew ); // 填充该点
		ptStack.pop();	// 出栈

		CPoint ptArround[ 4 ];
		ptArround[ 0 ] = CPoint( ptCurrent.x - 1, ptCurrent.y );
		ptArround[ 1 ] = CPoint( ptCurrent.x + 1, ptCurrent.y );
		ptArround[ 2 ] = CPoint( ptCurrent.x, ptCurrent.y - 1 );
		ptArround[ 3 ] = CPoint( ptCurrent.x, ptCurrent.y + 1 );
		
		// 将当前点点周围四个点压入栈中
		for ( int i = 0; i < 4; i ++ )
		{
			if( pDC->GetPixel( ptArround[ i ] ) == colorOld )
			{
				ptStack.push( ptArround[ i ] );  // 入栈
			}
		}
	}
}



(3)说明:上述两个函数只是形式不同,在算法效率上其实相差不大。


3、注:以上所诉的算法都是以像素点为基本单位实现的,也就是所,能够适应任意形状图形或色块的填充;但是,在此基础上,针对各种确定形状的图形,能够根据图形特点实现相应的填充算法,以提高填充效率。例如对于多边形,可以采用有效边填充法。