|
楼主 |
发表于 2012-12-27 11:21
|
显示全部楼层
n叉树转为二叉树的示例
将前文使用单向链表构建的树转为了二叉树,附件在1楼。该附件添加了较为详细的注释,供参考。
转二叉树的代码如下,在之前ParseData时,每个节点的链接数组下标改为由 -1 开始,并使用 -1 作为左子节点,0 作为右子节点。
[code=vb]
Sub RegularTreeToBinaryTree(arrNodes, nRoot)
' 二叉树的节点的链接数组中,-1 为左子节点,0 为右子节点
Dim i&, aChildren
aChildren = arrNodes(nRoot) ' 获得子节点(原树)地址数组
If UBound(aChildren) = 0 Then Exit Sub ' 如果没有子节点(原树)则退出
arrNodes(nRoot)(-1) = aChildren(1) ' 第一个子节点(原树)链接为当前节点的左子节点(二叉树)
For i = 1 To UBound(aChildren) - 1
arrNodes(aChildren(i))(0) = aChildren(i + 1)
' 每个子节点的右子节点(二叉树)为当前节点的下一个子节点(原树),最后一个不用加
Next
For i = 1 To UBound(aChildren)
Call RegularTreeToBinaryTree(arrNodes, aChildren(i))
' 递归遍历当前节点的全部子节点(原树)
Next
' 保留原树的链接信息,供比较
End Sub
[/code]
这样,当访问这个二叉树时,先序遍历就可以返回与之前的n叉树的深度遍历同样的顺序,遍历代码如下:
[code=vb]
Private Sub GetChildrenFromBinaryTree(nNode, aRows, nCount&, iLayer&)
' 先序遍历可获得同样顺序
Dim i&, j&, nRow&, aChildren
aChildren = aNodes(nNode)
If nNode <= UBound(aData) Then
' 产品节点作为树的根节点,没有信息,需跳过
nCount = nCount + 1
aRows(1, nCount) = iLayer
aRows(2, nCount) = nNode
' 添加当前节点行号至结果数组
End If
If Not IsEmpty(aChildren(-1)) And aChildren(-1) > 1 Then
' 有子节点,访问子节点,即向左走
iLayer = iLayer + 1 ' 层数 +1
Call GetChildrenFromBinaryTree(aChildren(-1), aRows, nCount, iLayer)
End If
iLayer = iLayer - 1
' 当前节点没有子节点或已经访问过,退回到上一节点,层数 -1
' 当由兄弟节点返回时,也会 -1,故在访问兄弟节点需 +1
If Not IsEmpty(aChildren(0)) And aChildren(0) > 1 Then
' 有兄弟节点,向右走
iLayer = iLayer + 1
Call GetChildrenFromBinaryTree(aChildren(0), aRows, nCount, iLayer)
End If
End Sub
[/code] |
|