C 此递归洪水填充实现的终止条件是什么?

C 此递归洪水填充实现的终止条件是什么?,c,recursion,sdl,flood-fill,C,Recursion,Sdl,Flood Fill,我设置了一个递归泛洪填充算法,它可以保持由于(我认为)达到堆栈溢出/递归深度而导致的分段故障。我不想弄乱堆栈限制,创建这个特定算法的迭代版本超出了我的技能水平。所以,我只希望函数在这么多循环之后停止,这样它只会安全地填充很小的区域 我已经创建了一个测试程序来处理终止条件的实现,但是我注意到,尽管完成了它的工作,该函数仍在运行。例如,在下面的代码中,让它运行200000次会正确地填充窗口,但300000次也是如此,当我让它运行400000次时,它会安全地在337977处停止循环。所以我很困惑到底是

我设置了一个递归泛洪填充算法,它可以保持由于(我认为)达到堆栈溢出/递归深度而导致的分段故障。我不想弄乱堆栈限制,创建这个特定算法的迭代版本超出了我的技能水平。所以,我只希望函数在这么多循环之后停止,这样它只会安全地填充很小的区域

我已经创建了一个测试程序来处理终止条件的实现,但是我注意到,尽管完成了它的工作,该函数仍在运行。例如,在下面的代码中,让它运行200000次会正确地填充窗口,但300000次也是如此,当我让它运行400000次时,它会安全地在337977处停止循环。所以我很困惑到底是什么让它停在了337977,我怎么能让它停在洪水的实际终点,我用我的眼睛可以看到,不到200000圈

#include <stdio.h>
#include <SDL2/SDL.h>
Uint32 myPixelColour(Uint32 *pixels, int x, int y, int windowWidth, int windowHeight)
{

    Uint32 thisPixelColour = 0;
    thisPixelColour = pixels[x + y * windowWidth];
    return thisPixelColour;
}

int mySameColour(Uint32 thisPixelColour, Uint32 thatPixelColour)
{
    return (thisPixelColour == thatPixelColour);
}

void myFill(Uint32 *pixels, int windowWidth, int windowHeight, int x, int y, Uint32 finColour, int *counter)
{
    if(!((x>=0) && (x<windowWidth) && (y>=0) && (y<windowHeight))) return;
    if(*counter == 400000) return;  /* 200000 fills the window, so does 300000 */
    printf("%d\n", *counter);
    *counter = *counter + 1;

    Uint32 ogColour = myPixelColour(pixels, x, y, windowWidth, windowHeight);
    if(mySameColour(ogColour, finColour)) return;
    pixels[x+y*windowWidth] = finColour;

    myFill(pixels, windowWidth, windowHeight, x, y+1, finColour, counter);
    myFill(pixels, windowWidth, windowHeight, x-1, y, finColour, counter);
    myFill(pixels, windowWidth, windowHeight, x, y-1, finColour, counter);
    myFill(pixels, windowWidth, windowHeight, x+1, y, finColour, counter);
}

int main(void)
{
    const int windowWidth = 400;
    const int windowHeight = 212;
    int counter;
    counter = 1;

    SDL_Window *window = SDL_CreateWindow("WindowTitle", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, windowWidth, windowHeight, SDL_WINDOW_SHOWN);
    SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, 0);
    SDL_Texture *texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, windowWidth, windowHeight);

    Uint32 *pixels = NULL;
    pixels = (Uint32 *) malloc (sizeof(Uint32)*(Uint32)windowWidth*(Uint32)windowHeight);
    memset(pixels, 255, (Uint32)windowWidth*(Uint32)windowHeight*sizeof(Uint32));

    Uint32 finColour = 0x99FFCC;

    SDL_Point mouse_position;
    int success = 1;
    while(success)
    {
        SDL_Event userAction;

        SDL_GetMouseState(&mouse_position.x, &mouse_position.y);

        SDL_UpdateTexture(texture, NULL, pixels, (int)((Uint32)windowWidth * sizeof(Uint32)));

        while(SDL_PollEvent(&userAction))
        {
            switch(userAction.type)
            {
                case SDL_QUIT: success = 0; break;
                case SDL_KEYDOWN:
                    if(userAction.key.keysym.sym == SDLK_f)
                    {
                        myFill(pixels, windowWidth, windowHeight, 1, 1, finColour, &counter);
                    }
                    break;
            }
        }

        SDL_RenderClear(renderer);
        SDL_RenderCopy(renderer, texture, NULL, NULL);
        SDL_RenderPresent(renderer);
    }
    free(pixels);
    SDL_DestroyTexture(texture);
    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);
    return 0;
}
#包括
#包括
Uint32 MyPixelColor(Uint32*像素,整数x,整数y,整数窗口宽度,整数窗口高度)
{
Uint32此像素颜色=0;
ThisPixelColor=像素[x+y*窗口宽度];
返回此像素颜色;
}
int mySameColour(Uint32 thisPixelColour,Uint32 thatPixelColour)
{
返回(ThisPixelColor==ThatPixelColor);
}
void myFill(Uint32*像素,int windowWidth,int windowHeight,int x,int y,Uint32 fincolor,int*计数器)
{

如果(!((x>=0)和&(x=0)和&(yy),您可能会访问特定像素两次。因此,整个部分实际上是彩色的20000倍。但总共需要3379977次迭代(因为一些错误插入的调用)。在递增计数器之前,您可能应该移动对
myamecolor
的检查。因为即使您实际上没有在函数中执行任何操作,您也错误地递增了计数器。@Ajay移动
myamecolor
会降低总计数,但输入
myFill
函数来检查颜色仍然会增加计数递归的另一个深度,对吗?如果达到递归极限导致SEGFULT,那么这就是我想要避免的。但是如果该条件失败,它会立即返回。所以没关系。假设你对像素1,1着色。然后你调用了1,2。现在1,2将再次调用1,1。但它什么都不做。即使计数器增加了。如果您担心额外的函数调用,可以在调用函数之前进行此检查。即在每次递归调用
myFill
之前,检查
mySameColor
。此外,如果您确实想测量“深度”,则应在离开函数时减小计数器(我假设您知道堆栈的工作原理)。在这种情况下,您也将看到它如何递增,然后由于返回而立即递减。