SQLite Forum

Breadth-first graph traversal
Login
I actually did read through that discussion but the solution is not what I'm looking for. Using the `path` and `instr` method you showed there will cut off paths that become cycles but it won't cut off paths that revisit nodes.

Take for example the directed-acyclic graph:

```
1
|\
2 3
|/
4
|\
5 6
|/
7
```

```
$ cat bfs_test.sql
create table edges(fromNode integer, toNode integer);
insert into edges(fromNode, toNode) values
    (1, 2),
    (1, 3),
    (2, 4),
    (3, 4),
    (4, 5),
    (4, 6),
    (5, 7),
    (6, 7);

with recursive
    bfs_tree(id, visited, distance) as (
        select 1, '/' || 1 || '/', 0
        union all
        select toNode, visited || toNode || '/', distance + 1
        from edges, bfs_tree
        where fromNode = id and instr(visited, '/' || toNode || '/') == 0
        order by 3 asc
    )
select * from bfs_tree;

$ sqlite3 < bfs_test.sql
1|/1/|0
2|/1/2/|1
3|/1/3/|1
4|/1/2/4/|2
4|/1/3/4/|2
5|/1/2/4/5/|3
6|/1/2/4/6/|3
5|/1/3/4/5/|3
6|/1/3/4/6/|3
7|/1/2/4/5/7/|4
7|/1/2/4/6/7/|4
7|/1/3/4/5/7/|4
7|/1/3/4/6/7/|4
```