You can use the standard DFS and BFS algorithms, but instead of getting the child nodes of a particular node from a pre-built tree structure, you can compute them as needed.
For a BFS-numbered, complete K-ary tree of height H, the i-th child of a node N at depth D is:
K*N + 1 + i
A derivation of this formula when i = 0
(first child) is provided here.
For a DFS-numbered, complete K-ary tree of height H, the i-th child of a node N at depth D is given by a much uglier formula:
N + 1 + i*step where step = (K^(H - D) - 1) / (K - 1)
Here is a rough explanation of this formula:
For a node N at depth D in a DFS-numbered K-ary tree of height H, its first child is simply N+1 because it is the next node to be visited in a depth-first traversal. The second child of N will be visited directly after visiting the entire sub-tree rooted at the first child (N+1), which is itself a complete K-ary tree of height H - (D + 1)
. The size of any complete, K-ary tree is given by the sum of a finite geometric series as explained here. The size of said sub-tree is the distance between the first and second children, and, in fact, it is the same distance between all siblings since each of their sub-trees are the same size. If we call this distance step
, then:
1st child is N + 1
2nd child is N + 1 + step
3rd child is N + 1 + step + step
...and so on.
Below is a Python implementation (note: the dfs
function uses the BFS formula, because it is converting from DFS to BFS, and vice-versa for the bfs
function.):
def dfs(K, H):
stack = list()
push, pop = list.append, list.pop
push(stack, (0, 0))
while stack:
label, depth = pop(stack)
yield label
if depth + 1 > H: # leaf node
continue
for i in reversed(range(K)):
push(stack, (K*label + 1 + i, depth + 1))
def bfs(K, H):
from collections import deque
queue = deque()
push, pop = deque.append, deque.popleft
push(queue, (0, 0))
while queue:
label, depth = pop(queue)
yield label
if depth + 1 > H: # leaf node
continue
step = (K**(H - depth) - 1) // (K - 1)
for i in range(K):
push(queue, (label + 1 + i*step, depth + 1))
print(list(dfs(2, 3)))
print(list(bfs(2, 3)))
print(list(dfs(3, 2)))
print(list(bfs(3, 2)))
The above will print:
[0, 1, 3, 7, 8, 4, 9, 10, 2, 5, 11, 12, 6, 13, 14]
[0, 1, 8, 2, 5, 9, 12, 3, 4, 6, 7, 10, 11, 13, 14]
[0, 1, 4, 5, 6, 2, 7, 8, 9, 3, 10, 11, 12]
[0, 1, 5, 9, 2, 3, 4, 6, 7, 8, 10, 11, 12]