2013-07-28 50 views
0

這裏是一個例子,應該如何看(這是同樣的例子的代碼使用) enter image description here節點和子結構的混亂,混淆

的代碼開始從1級改變到2的水平時把螺絲擰緊發生了巨大的混亂,我根本不理解它。

下面是代碼

Public Class Node 
     Public label As Byte 
     Public visited As Boolean = False 
     Public level As Integer 

     Public Sub New(ByVal label As Byte, ByVal level As Integer) 
      Me.label = label 
      Me.level = level 
     End Sub 
    End Class 

    Public rootNodes As New List(Of Node) 
    Public nodes As New List(Of Node) 
    Dim adjMatrix As Byte(,) 
    Dim setDimensions As Boolean = False 

    Public Sub connectNode(ByVal start As Node, ByVal endd As Node) 
     'This method will be called to make connect two nodes 
     If setDimensions = False Then 
      ReDim Preserve adjMatrix(999 - 1, 999) 
      setDimensions = True 
     End If 
     Dim startIndex As Integer = nodes.IndexOf(start) 
     Dim endIndex As Integer = nodes.IndexOf(endd) 
     adjMatrix(startIndex, endIndex) = 1 
     adjMatrix(endIndex, startIndex) = 1 
    End Sub 

    Private Function getUnvisitedChildNode(ByVal n As Node) As Node 
     Dim index As Integer = nodes.IndexOf(n) 
     Dim j As Integer = 0 

     Do While j < nodes.Count 
      If adjMatrix(index, j) = 1 AndAlso nodes(j).visited = False Then 
       Return nodes(j) 
      End If 
      j += 1 
     Loop 
     Return Nothing 
    End Function 

    Private Sub clearNodes() 
     For Each n As Node In nodes 
      n.visited = False 
     Next 
    End Sub 

    Private Sub printNode(ByVal n As Node) 
     Debug.Print(n.label & " ") 
    End Sub 

    Public Enum Operation 
     LessThan = 0 
     GreaterThan = 1 
    End Enum 

    Public Function getPossibleNumbersForFirstByte(ByVal op As Operation, ByVal operationOf As Byte, ByVal numbersAlreadyUsed As List(Of Byte), ByVal totalSize As Long) As List(Of Byte) 
     Dim possibleNumbers As New List(Of Byte) 
     Dim tempNumber As Integer = -1 

     While True 
      If op = Operation.LessThan Then 
       tempNumber = IIf(tempNumber = -1, operationOf - 1, tempNumber - 1) 
      ElseIf op = Operation.GreaterThan Then 
       tempNumber = IIf(tempNumber = -1, operationOf + 1, tempNumber + 1) 
      End If 

      If tempNumber < 1 OrElse tempNumber > totalSize Then 
       Exit While 
      End If 
      If numbersAlreadyUsed Is Nothing OrElse numbersAlreadyUsed.Contains(tempNumber) = False Then 
       possibleNumbers.Add(tempNumber) 
      End If 
     End While 
     Return possibleNumbers 
    End Function 

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click 
     test() 
    End Sub 

    Sub test() 
     'Dim actualNumbers() As Byte = {5, 6, 1, 9, 7, 3, 8, 2, 4, 10} 

     Dim actualNumberList As New List(Of Byte) 
     actualNumberList.AddRange({5, 6, 1, 9, 7, 3, 8, 2, 4, 10}) 
     Dim ListofGTLT() As Byte = {1, 0, 1, 0, 0, 1, 0, 1, 1} 

     Dim firstNumber As Byte = actualNumberList(0) 
     Dim possibleNumbersToUse As New List(Of Byte) 
     Dim numbersAlreadyUsed As New List(Of Byte) 

     For currentLevel = 0 To UBound(ListofGTLT) 
      'clear visited nodes. 
      clearNodes() 

      If currentLevel = 0 Then 
       'Generates Level 0 of all possible values in the first offset. 
       possibleNumbersToUse = getPossibleNumbersForFirstByte(ListofGTLT(currentLevel), firstNumber, Nothing, 10) 
       Dim n As Node 
       'Generates parent nodes of all possible values in the first offset. 
       For Each possibleNumber As Byte In possibleNumbersToUse 
        n = New Node(possibleNumber, 0) 
        rootNodes.Add(n) 
        nodes.Add(n) 
       Next 
      Else 
       Dim rootNode As Node 
       For Each rootNode In rootNodes 
        'Clear numbers already used. 
        numbersAlreadyUsed.Clear() 
        'Set already exists first value (known value). 
        numbersAlreadyUsed.Add(firstNumber) 

        If currentLevel = 1 Then 
         'Gets all the numbers which are possible connections. 
         possibleNumbersToUse = getPossibleNumbersForFirstByte(ListofGTLT(currentLevel), rootNode.label, numbersAlreadyUsed, 10) 

         Dim n As Node 
         'Setup connections with new nodes to root node. 
         For Each value As Byte In possibleNumbersToUse 
          n = New Node(value, 1) 
          nodes.Add(n) 
          'Debug.Print("[Connection]: " & rootNode.label & " = " & n.label) 
          connectNode(rootNode, n) 
         Next 
        Else 
         numbersAlreadyUsed.Add(rootNode.label) 

         Dim child = getUnvisitedChildNode(rootNode) 
         Do While child IsNot Nothing 
          Debug.Print("------------------------------------------") 
          Debug.Print("| Root = " & rootNode.label) 
          Debug.Print("| Child Level = " & child.level) 
          Debug.Print("| Child = " & child.label) 
          Debug.Print("------------------------------------------") 

          'Add to already existing values the child connection node. 
          If numbersAlreadyUsed.Contains(child.label) = False Then 
           If child.level = (currentLevel - 1) Then 
            'Gets next possible numbers which are possible connections. 
            possibleNumbersToUse = getPossibleNumbersForFirstByte(ListofGTLT(currentLevel), child.label, numbersAlreadyUsed, 10) 

            Dim n As Node 
            'Setup connections with new nodes to child node. 
            For Each value As Byte In possibleNumbersToUse 
             n = New Node(value, currentLevel) 
             nodes.Add(n) 
             connectNode(child, n) 
            Next 

            If child.level = 1 Then 
             'Finish all the level 1 childs for the current Root Node. 
             child.visited = True 
             child = getUnvisitedChildNode(rootNode) 
             Continue Do 
            Else 
             numbersAlreadyUsed.Add(child.label) 
             child.visited = True 
             child = getUnvisitedChildNode(child) 
             Continue Do 
            End If 

           Else 
            numbersAlreadyUsed.Add(child.label) 
            child.visited = True 
            child = getUnvisitedChildNode(child) 
            Continue Do 
           End If 
          Else 
           numbersAlreadyUsed.Add(child.label) 
           child.visited = True 
           child = getUnvisitedChildNode(child) 
           Continue Do 
          End If 
         Loop 
        End If 
       Next 
      End If 
     Next 
    End Sub 
+0

「巨​​大的混亂」是什麼意思? –

回答

1

,而不是實施自己的類,用樹節點類,它是專爲這一點,使代碼更容易理解,並具有可原產於額外的好處TreeView,這意味着我們所要做的就是添加基節點並調用ExpandAll,並且我們有一個樹的圖形表示。另外你想做的事很適合遞歸例程。這是一種構建樹結構的方法。無論何時添加子節點,它都會跳過樹中已有值的任何值。

Private Sub btnAnswers_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click 
     'Declare initial treenode with the value we want. 
     Dim Tree As New TreeNode("5") 
     'Declare the string of bits. 
     Dim input As String = "1001001001" 
     'Start the recursive routine 
     CalculateTreeNodes(Tree, input) 
     'Show the tree 
     TreeView1.Nodes.Add(Tree) 
     TreeView1.ExpandAll()h 
    End Sub 
    Private Sub CalculateTreeNodes(CurrentNode As TreeNode, directions As String) 
     If directions = "" Then Return 
     'Parse the text of the current node as byte 
     Dim value As Byte = Byte.Parse(CurrentNode.Text) 
     'Get the direction we want and truncate the string 
     Dim direction As Directions = CType([Enum].Parse(GetType(Directions), directions(0).ToString), Directions) 
     If directions.Length > 0 Then 
      directions = directions.Substring(1) 
     End If 
     'Get a list of the values of all the parent nodes above this one. 
     Dim Values As New List(Of Byte) 
     GetPrevValues(CurrentNode, Values) 
      'build our child nodes based on the direction we want. 
      Select Case direction 
       Case WindowsApplication7.Directions.Higher 
        For i As Byte = value + 1 To 10 
        If Not Values.Contains(i) Then 
         Dim node As New TreeNode(i.ToString) 
         CurrentNode.Nodes.Add(node) 
         'Calculate the children for each node 
         CalculateTreeNodes(node, directions) 
        End If 
        Next 
       Case WindowsApplication7.Directions.Lower 
        For i As Byte = 1 To value - 1 
        If Not Values.Contains(i) Then 
         Dim node As New TreeNode(i.ToString) 
         CurrentNode.Nodes.Add(node) 
         CalculateTreeNodes(node, directions) 
        End If 
        Next 
      End Select 
    End Sub 
    'recursive routine to find the parent values. 
    Private Sub GetPrevValues(CurrentNode As TreeNode, Values As List(Of Byte)) 
     If Not CurrentNode Is Nothing Then 
      Values.Add(Byte.Parse(CurrentNode.Text)) 
      GetPrevValues(CurrentNode.Parent, Values) 
     End If 
    End Sub 
End Class 
Public Enum Directions 
    Higher = 1 
    Lower = 0 
End Enum 

要找到你可以使用條件來檢查是否directions下降到一個字符最長的分支,那麼任何一個孩子將是最長的分支。

+0

感謝代碼,它看起來很完美,它甚至可視化現在得弄清楚如何檢查最長的分支,並按順序查找它們,我正在考慮使用http://www.codeproject.com/Articles/32212/Introduction圖形與廣度優先搜索BF對該文章的深度優先搜索(DFS)。 – SSpoke

+1

在我的回答中,我給了你一種找到樹中最深的孩子的方法。你可以做的是聲明一個新的字節列表並調用'GetPrevValues',傳遞子節點和新列表,並使用Join方法構建一串逗號分隔值並將其添加到字符串列表中。現在你可以操縱內容和/或訂單,但是你喜歡。 – tinstaafl

+0

嘿,如果方向是下降到一個?你確定如果它下降到1它會發現它?它的長度不一定是0嗎?這是我試過的只發現8長度列表,應該是9(不包括父母(5))http://pastebin.com/h85Czm7V – SSpoke