How to parse a table into a binary tree in VB.NET

1 Answer

0 votes
Imports System
Imports System.Collections.Generic
 
'===============================================================
'   Node class: represents a general tree node stored as a
'   binary tree using Left‑Child / Right‑Sibling representation.
'
'   Left  → first child
'   Right → next sibling
'===============================================================
Public Class Node
    Public Property Id As Integer
    Public Property Name As String
    Public Property Left As Node     ' first child
    Public Property Right As Node    ' next sibling
 
    Public Sub New(i As Integer, n As String)
        Id = i
        Name = n
        Left = Nothing
        Right = Nothing
    End Sub
End Class
 
'===============================================================
'   Print the tree with indentation
'===============================================================
Module TreePrinter
 
    Public Sub PrintTree(root As Node, Optional depth As Integer = 0)
        If root Is Nothing Then Exit Sub
 
        ' show ROOT explicitly on its own line
        If depth = 0 Then
            Console.WriteLine("ROOT")
        End If
 
        ' indentation for the node itself
        For i As Integer = 1 To depth + 1
            Console.Write("  ")
        Next
 
        ' print ID with leading zero if needed
        Console.WriteLine($"{root.Id:00} - {root.Name}")
 
        ' first child
        PrintTree(root.Left, depth + 1)
 
        ' next sibling
        If depth = 0 AndAlso root.Right IsNot Nothing Then
            ' restart ROOT for next top-level node
            PrintTree(root.Right, 0)
        Else
            PrintTree(root.Right, depth)
        End If
    End Sub
 
End Module
 
'===============================================================
'   Build the tree using Left‑Child / Right‑Sibling representation
'===============================================================
Module TreeBuilder
 
    Public Function BuildTree(
        table As List(Of Tuple(Of Integer, String, Integer)),
        nodesOut As Dictionary(Of Integer, Node)
    ) As Node
 
        ' Create nodes
        For Each row In table
            Dim id = row.Item1
            Dim name = row.Item2
            nodesOut(id) = New Node(id, name)
        Next
 
        Dim root As Node = Nothing
 
        ' Attach children and siblings
        For Each row In table
            Dim id = row.Item1
            Dim parentId = row.Item3
            Dim current = nodesOut(id)
 
            If parentId = 0 Then
                ' top-level node → sibling chain under root
                If root Is Nothing Then
                    root = current
                Else
                    Dim p = root
                    While p.Right IsNot Nothing
                        p = p.Right
                    End While
                    p.Right = current
                End If
            Else
                Dim parent = nodesOut(parentId)
 
                ' attach as first child or next sibling
                If parent.Left Is Nothing Then
                    parent.Left = current
                Else
                    Dim p = parent.Left
                    While p.Right IsNot Nothing
                        p = p.Right
                    End While
                    p.Right = current
                End If
            End If
        Next
 
        Return root
    End Function
 
End Module
 
'===============================================================
'   Main Program
'===============================================================
Module Program
 
    Sub Main()
 
        ' Example table
		' //             Id  Name    ParentId 
        Dim table As New List(Of Tuple(Of Integer, String, Integer)) From {
            Tuple.Create(1, "Node 1", 0),
            Tuple.Create(2, "Node 1.1", 1),
            Tuple.Create(3, "Node 2", 0),
            Tuple.Create(4, "Node 1.1.1", 2),
            Tuple.Create(5, "Node 2.1", 3),
            Tuple.Create(6, "Node 2.3.1", 3),
            Tuple.Create(7, "Node 1.2", 1),
            Tuple.Create(8, "Node 1.3", 1),
            Tuple.Create(9, "Node 1.3.1", 8),
            Tuple.Create(10, "Node 2.4", 3),
            Tuple.Create(11, "Node 2.1.1", 5),
            Tuple.Create(12, "Node 2.1.1.6", 11)
        }
 
        Dim nodes As New Dictionary(Of Integer, Node)
 
        ' Build tree
        Dim root As Node = TreeBuilder.BuildTree(table, nodes)
 
        ' Print tree
        TreePrinter.PrintTree(root)
 
    End Sub
 
End Module
 

'
' run:
'
' ROOT
'   01 - Node 1
'     02 - Node 1.1
'       04 - Node 1.1.1
'     07 - Node 1.2
'     08 - Node 1.3
'       09 - Node 1.3.1
' ROOT
'   03 - Node 2
'     05 - Node 2.1
'       11 - Node 2.1.1
'         12 - Node 2.1.1.6
'     06 - Node 2.3.1
'     10 - Node 2.4
'

 



answered Sep 4 by avibootz
edited Sep 4 by avibootz
...