1 #Region "Microsoft.VisualBasic::5557f46e84be9886582f93fd87df5fe6, Microsoft.VisualBasic.Core\ComponentModel\DataStructures\Tree\TreeNodeBase.vb"
2
3     ' Author:
4     
5     '       asuka (amethyst.asuka@gcmodeller.org)
6     '       xie (genetics@smrucc.org)
7     '       xieguigang (xie.guigang@live.com)
8     
9     ' Copyright (c) 2018 GPL3 Licensed
10     
11     
12     ' GNU GENERAL PUBLIC LICENSE (GPL3)
13     
14     
15     ' This program is free software: you can redistribute it and/or modify
16     ' it under the terms of the GNU General Public License as published by
17     ' the Free Software Foundation, either version 3 of the License, or
18     ' (at your option) any later version.
19     
20     ' This program is distributed in the hope that it will be useful,
21     ' but WITHOUT ANY WARRANTY; without even the implied warranty of
22     ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23     ' GNU General Public License for more details.
24     
25     ' You should have received a copy of the GNU General Public License
26     ' along with this program. If not, see <http://www.gnu.org/licenses/>.
27
28
29
30     ' /********************************************************************************/
31
32     ' Summaries:
33
34     '     Class TreeNodeBase
35     
36     '         Properties: ChildNodes, FullyQualifiedName, IsLeaf, IsRoot, Name
37     '                     Parent
38     
39     '         Constructor: (+1 OverloadsSub New
40     
41     '         Function: __travelInternal, GetEnumerator, GetLeafNodes, GetNonLeafNodes, GetRootNode
42     '                   IEnumerable_GetEnumerator, IteratesAllChilds, MaxTravelDepth
43     
44     '         Sub: AddChild, AddChildren, ChildCountsTravel
45     
46     
47     ' /********************************************************************************/
48
49 #End Region
50
51 Imports System.Runtime.CompilerServices
52
53 Namespace ComponentModel.DataStructures.Tree
54
55     ''' <summary>
56     ''' Generic Tree Node base class
57     ''' </summary>
58     ''' <typeparam name="T"></typeparam>
59     ''' <remarks>https://www.codeproject.com/Articles/345191/Simple-Generic-Tree</remarks>
60     Public MustInherit Class TreeNodeBase(Of T As {
61                                               Class, ITreeNode(Of T)
62                                           })
63         Implements ITreeNode(Of T), IEnumerable(Of T)
64
65         ''' <summary>
66         ''' 
67         ''' </summary>
68         ''' <param name="name"></param>
69         Protected Sub New(name As String)
70             Me.Name = name
71             ChildNodes = New List(Of T)()
72         End Sub
73
74         ''' <summary>
75         ''' Name
76         ''' </summary>
77         Public Property Name() As String
78
79         ''' <summary>
80         ''' Parent
81         ''' </summary>
82         Public Property Parent() As T Implements ITreeNode(Of T).Parent
83
84         ''' <summary>
85         ''' Children
86         ''' </summary>
87         Public Property ChildNodes() As List(Of T) Implements ITreeNode(Of T).ChildNodes
88
89         ''' <summary>
90         ''' Me/this
91         ''' </summary>
92         Public MustOverride ReadOnly Property MySelf() As T
93
94         ''' <summary>
95         ''' True if a Leaf Node
96         ''' </summary>
97         Public ReadOnly Property IsLeaf() As Boolean Implements ITreeNode(Of T).IsLeaf
98             <MethodImpl(MethodImplOptions.AggressiveInlining)>
99             Get
100                 Return ChildNodes.Count = 0
101             End Get
102         End Property
103
104         ''' <summary>
105         ''' True if the Root of the Tree
106         ''' </summary>
107         Public ReadOnly Property IsRoot() As Boolean Implements ITreeNode(Of T).IsRoot
108             <MethodImpl(MethodImplOptions.AggressiveInlining)>
109             Get
110                 Return Parent Is Nothing
111             End Get
112         End Property
113
114         <MethodImpl(MethodImplOptions.AggressiveInlining)>
115         Public Function MaxTravelDepth() As Integer
116             Return __travelInternal(Me.MySelf)
117         End Function
118
119         Private Shared Function __travelInternal(child As T) As Integer
120             Dim l As New List(Of Integer) From {0}
121
122             For Each c As T In child.ChildNodes
123                 l.Add(__travelInternal(child:=c))
124             Next
125
126             ' 最后的 +1 是因为当前的对象自己本身也是一层节点
127             Return l.Max + 1
128         End Function
129
130         ''' <summary>
131         ''' List of Leaf Nodes
132         ''' </summary>
133         ''' 
134         <MethodImpl(MethodImplOptions.AggressiveInlining)>
135         Public Function GetLeafNodes() As List(Of T)
136             Return ChildNodes.Where(Function(x) x.IsLeaf).AsList()
137         End Function
138
139         ''' <summary>
140         ''' List of Non Leaf Nodes
141         ''' </summary>
142         ''' 
143         <MethodImpl(MethodImplOptions.AggressiveInlining)>
144         Public Function GetNonLeafNodes() As List(Of T)
145             Return ChildNodes.Where(Function(x) Not x.IsLeaf).AsList()
146         End Function
147
148         ''' <summary>
149         ''' Get the Root Node of the Tree
150         ''' </summary>
151         Public Function GetRootNode() As T Implements ITreeNode(Of T).GetRootNode
152             If Parent Is Nothing Then
153                 Return MySelf
154             End If
155
156             Return Parent.GetRootNode()
157         End Function
158
159         ''' <summary>
160         ''' Dot separated name from the Root to this Tree Node
161         ''' </summary>
162         Public ReadOnly Property FullyQualifiedName() As String Implements ITreeNode(Of T).FullyQualifiedName
163             Get
164                 If Parent Is Nothing Then
165                     Return Name
166                 End If
167
168                 Return String.Format("{0}.{1}", Parent.FullyQualifiedName(), Name)
169             End Get
170         End Property
171
172         ''' <summary>
173         ''' Add a Child Tree Node
174         ''' </summary>
175         ''' <param name="child"></param>
176         Public Sub AddChild(child As T)
177             child.Parent = MySelf
178             ChildNodes.Add(child)
179         End Sub
180
181         ''' <summary>
182         ''' Add a collection of child Tree Nodes
183         ''' </summary>
184         ''' <param name="children"></param>
185         Public Sub AddChildren(children As IEnumerable(Of T))
186             For Each child As T In children
187                 AddChild(child)
188             Next
189         End Sub
190
191         Public Sub ChildCountsTravel(distribute As Dictionary(Of StringDouble), Optional getID As Func(Of T, String) = NothingImplements ITreeNode(Of T).ChildCountsTravel
192             Dim count As Double = ChildNodes.Count
193             Dim childCounts As New Dictionary(Of StringDouble)
194
195             If getID Is Nothing Then
196                 getID = Function(x) x.FullyQualifiedName
197             End If
198
199             For Each child As T In ChildNodes
200                 ' 首先进行递归visit,之后才会有计数数据
201                 Call childCounts.Clear()
202                 Call child.ChildCountsTravel(childCounts, getID)
203                 For Each counts In childCounts
204                     Call distribute.Add(counts.Key, counts.Value)
205                     count += counts.Value
206                 Next
207             Next
208
209             Dim key$ = getID(MySelf)
210             Call distribute.Add(key, count)
211         End Sub
212
213         ''' <summary>
214         ''' Iterates all of my childs
215         ''' </summary>
216         ''' <returns></returns>
217         Public Iterator Function GetEnumerator() As IEnumerator(Of T) Implements IEnumerable(Of T).GetEnumerator
218             For Each myChild As T In ChildNodes
219                 Yield myChild
220
221                 For Each child As T In myChild.IteratesAllChilds
222                     Yield child
223                 Next
224             Next
225         End Function
226
227         Private Iterator Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
228             Yield GetEnumerator()
229         End Function
230
231         Public Function IteratesAllChilds() As IEnumerable(Of T) Implements ITreeNode(Of T).IteratesAllChilds
232             Return Me
233         End Function
234     End Class
235 End Namespace