VBA编写代码遍历二叉树路径的问题

在一个excel中,这样表示一个二叉树:
跟节点 左子节点 右子节点
1 2 3
2 4 5
3 6 7
4 9 10
5 11 12
6 13 14
如何编写VBA代码,遍历所有的路径?

可以使用递归的方式来遍历这个二叉树,以下是一个遍历所有路径的VBA代码示例:

Sub TraverseBinaryTree(ByVal rootRowIndex As Integer, ByVal nodeColumnIndex As Integer, ByVal path As String)
    Dim currentNodeValue As Integer
    Dim leftNodeValue As Integer
    Dim rightNodeValue As Integer
    
    ' 获取当前节点的值、左子节点的值和右子节点的值
    currentNodeValue = Cells(rootRowIndex, nodeColumnIndex).Value
    leftNodeValue = Cells(rootRowIndex + 1, nodeColumnIndex - 1).Value
    rightNodeValue = Cells(rootRowIndex + 1, nodeColumnIndex).Value
    
    ' 更新路径
    path = path & " " & CStr(currentNodeValue)
    
    ' 如果当前节点是叶子节点,则输出路径
    If leftNodeValue = 0 And rightNodeValue = 0 Then
        Debug.Print path
    Else ' 否则递归遍历子树
        If leftNodeValue <> 0 Then
            TraverseBinaryTree rootRowIndex + 2, nodeColumnIndex - 2, path
        End If
        If rightNodeValue <> 0 Then
            TraverseBinaryTree rootRowIndex + 2, nodeColumnIndex + 2, path
        End If
    End If
End Sub

在上述代码中,rootRowIndexnodeColumnIndex分别表示当前节点在Excel表格中的行索引和列索引,path表示从根节点到当前节点的路径。首先获取当前节点的值和左右子节点的值,然后更新路径。如果当前节点是叶子节点,则输出路径;否则递归遍历左子树和右子树。递归调用时,需要根据节点在Excel表格中的位置计算下一层节点的行索引和列索引。在调用该子程序时,可以将根节点的行索引和列索引传递给TraverseBinaryTree函数,如下所示:

Sub TestTraverseBinaryTree()
    TraverseBinaryTree 1, 2, ""
End Sub

运行上述测试子程序即可输出所有路径。

该回答引用GPTᴼᴾᴱᴺᴬᴵ
以下是修正后的代码:

Sub TraverseBinaryTree(ByVal node As Range, ByVal path As String)
    Dim value As Integer
    value = node.Value
    path = path & " " & value ' 将当前节点加入路径
    If node.Offset(1, 0).Value <> "" Then ' 如果有左子节点
        TraverseBinaryTree node.Offset(1, 0), path ' 遍历左子树
    End If
    If node.Offset(1, 1).Value <> "" Then ' 如果有右子节点
        TraverseBinaryTree node.Offset(1, 1), path ' 遍历右子树
    End If
    If node.Offset(1, 0).Value = "" And node.Offset(1, 1).Value = "" Then ' 如果是叶子节点
        Debug.Print path ' 输出路径
    End If
End Sub


对比之前的代码,主要是将 path 变量的传递改为了 ByRef,确保每次递归能正确地累加节点的值。

Private Sub TraverseTree(root As Range, Optional path As String)
    If root Is Nothing Then Exit Sub
    If Len(path) = 0 Then
        path = CStr(root.Value)
    Else
        path = path & "->" & CStr(root.Value)
    End If
    If root.Offset(, 1).Value <> "" And root.Offset(1).Value <> "" Then
        TraverseTree root.Offset(, 1), path
        TraverseTree root.Offset(1), path
    Else
        Debug.Print path
    End If
End Sub

Sub StartTraversal()
    TraverseTree Range("A1")
End Sub

根据给定的根节点和当前路径遍历该树。如果子节点不为空,则将其添加到当前路径中并继续向下遍历。一旦到达叶节点,该路径将被打印出来。

不知道你这个问题是否已经解决, 如果还没有解决的话:

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^