Non-recursive implementation of Flood Fill algorithm?

前端 未结 3 1146
失恋的感觉
失恋的感觉 2021-01-02 05:32

I\'m working on a small drawing application in Java. I\'m trying to create a \'bucket-fill\' tool by implementing the Flood Fill algorithm.

I tried using a recursion

相关标签:
3条回答
  • 2021-01-02 05:47

    You basically have two ways to implement a flood fill algorithm non-recursively. The first method has been clearly explained by sukunrt in which you use a queue to implement breadth first search.

    Alternatively, you can implement the recursive DFS non-recursively by using an implicit stack. For example, the following code implements a non-recursive DFS on a graph that has nodes as integers. In this code you use an array of Iterator to keep track of the processed neighbors in every node's adjacency list. The complete code can be accessed here.

    public NonrecursiveDFS(Graph G, int s) {
            marked = new boolean[G.V()];
    
            // to be able to iterate over each adjacency list, keeping track of which
            // vertex in each adjacency list needs to be explored next
            Iterator<Integer>[] adj = (Iterator<Integer>[]) new Iterator[G.V()];
            for (int v = 0; v < G.V(); v++)
                adj[v] = G.adj(v).iterator();
    
            // depth-first search using an explicit stack
            Stack<Integer> stack = new Stack<Integer>();
            marked[s] = true;
            stack.push(s);
            while (!stack.isEmpty()) {
                int v = stack.peek();
                if (adj[v].hasNext()) {
                    int w = adj[v].next();
                    if (!marked[w]) {
                        // discovered vertex w for the first time
                        marked[w] = true;
                        // edgeTo[v] = w;
                        stack.push(w);
                    }
                }
                else {
                    // v's adjacency list is exhausted
                    stack.pop();
                }
            }
        }
    
    0 讨论(0)
  • 2021-01-02 05:58

    I'm assuming that you have some sort of a grid where you receive the coordinates of the location from where you would like to fill the area.

    Recursive flood fill algorithm is DFS. You can do a BFS to convert it to nonrecursive.

    Basically the idea is similar in both the algorithms. You have a bag in which the nodes that are yet to be seen are kept. You remove a node from the bag and put the valid neighbors of the node back into the bag. If the bag is a stack you get a DFS. If it's a queue you get a BFS.

    the pseudocode is roughly this.

    flood_fill(x,y, check_validity)
       //here check_validity is a function that given coordinates of the point tells you whether
       //the point should be colored or not
       Queue q
       q.push((x,y))
       while (q is not empty)
           (x1,y1) = q.pop()
           color(x1,y1)
    
           if (check_validity(x1+1,y1))
                q.push(x1+1,y1)
           if (check_validity(x1-1,y1))
                q.push(x1-1,y1)
           if (check_validity(x1,y1+1))
                q.push(x1,y1+1)
           if (check_validity(x1,y1-1))
                q.push(x1,y1-1)
    

    NOTE: make sure that check_validity takes into account whether the point is already colored or not.


    • DFS: Depth First Search
    • BFS: Breadth First Search
    0 讨论(0)
  • 2021-01-02 06:02

    EDIT: watch this video: https://www.youtube.com/watch?v=LvacRISl99Y

    My results using the above method are about 10 million pixels per second. I researched it to fill 2 billion voxels space with laberinthine structures, in about 2-3 minutes, avoiding stack overflows.

    Instead of using complex logic to track previously verified neighbor spaces, I have a 2D array that records all the verified spaces. Reading from the verified array is 2-3 instructions: IF pixel[23,23] is verified, THEN fill it and check it's neighbors and write them to the verified array (fill pixel[23,23], verify pixel[23+1,23]and the three others. code is in the video.

    0 讨论(0)
提交回复
热议问题