|
|
|
Click here to copy the following block | Option Explicit
Private Type Node value As Variant Deleteed As Boolean ParentIdx As Long GEIdx As Long LTIdx As Long End Type
Dim NodeList() As Node
Dim Root As Long Dim FreeStart As Long
Const INITIAL_NODES As Long = 50 Const ALLOC_AMT As Long = 50 Const FREE_INDICATOR = -5 Const LEAF_NODE = -1 Const ROOT_NODE = -1
Private m_ChunkSize As Long
Private m_Count As Long
Public Function Add(ByVal vKeyVal As Variant) As Long Dim ndx As Long Dim nextFreeIndx As Long Dim EndOfTree As Boolean
If FreeStart = 0 Then ExpandList m_ChunkSize ndx = FreeStart nextFreeIndx = NodeList(ndx).GEIdx With NodeList(ndx) .ParentIdx = ROOT_NODE .GEIdx = LEAF_NODE .LTIdx = LEAF_NODE .Deleteed = False .value = vKeyVal End With
If Root = 0 Then Root = ndx EndOfTree = True End If If Not EndOfTree Then AddHelper ndx, Root End If
FreeStart = nextFreeIndx m_Count = m_Count + 1 Add = ndx End Function Public Function Find(vKey As Variant) As Variant If Root = 0 Then Find = "NOT FOUND" Exit Function End If Find = FindHelper(vKey, Root) End Function
Public Function Traverse() As Variant Dim st$ Process Root, st Traverse = st End Function
Public Function RemoveNode(vKey As Variant) As Variant
Dim IdxToBeRemoved& IdxToBeRemoved = FindIndex(vKey) RemoveNode = 0 If IdxToBeRemoved = -5 Then Exit Function RemoveNode = NodeList(IdxToBeRemoved).value m_Count = m_Count - 1
If NodeList(IdxToBeRemoved).GEIdx = LEAF_NODE And NodeList(IdxToBeRemoved) _ .LTIdx = LEAF_NODE Then If IdxToBeRemoved = Root Then Root = 0 MarkNodeAsFree IdxToBeRemoved Exit Function End If If NodeList(NodeList(IdxToBeRemoved).ParentIdx).GEIdx = IdxToBeRemoved _ Then NodeList(NodeList(IdxToBeRemoved).ParentIdx).GEIdx = LEAF_NODE Else NodeList(NodeList(IdxToBeRemoved).ParentIdx).LTIdx = LEAF_NODE End If MarkNodeAsFree IdxToBeRemoved Exit Function End If
If NodeList(IdxToBeRemoved).GEIdx = LEAF_NODE Or NodeList(IdxToBeRemoved) _ .LTIdx = LEAF_NODE Then If NodeList(IdxToBeRemoved).ParentIdx = ROOT_NODE Then MakeSingleChildRoot IdxToBeRemoved Else PointSingleChildToGrandparent IdxToBeRemoved End If MarkNodeAsFree IdxToBeRemoved Exit Function End If If NodeList(IdxToBeRemoved).ParentIdx = ROOT_NODE Then RootWithTwoChildProcess IdxToBeRemoved Else TwoChildProcess IdxToBeRemoved End If End Function
Private Sub RootWithTwoChildProcess(IdxToBeRemoved&)
Dim GEChild&, LTChild&
GEChild = NodeList(IdxToBeRemoved).GEIdx LTChild = NodeList(IdxToBeRemoved).LTIdx
NodeList(GEChild).ParentIdx = ROOT_NODE Root = GEChild MarkNodeAsFree IdxToBeRemoved AddTree LTChild, Root End Sub
Private Sub TwoChildProcess(IdxToBeRemoved&)
Dim GEChild&, LTChild&, GrandParent& GEChild = NodeList(IdxToBeRemoved).GEIdx LTChild = NodeList(IdxToBeRemoved).LTIdx GrandParent = NodeList(IdxToBeRemoved).ParentIdx If NodeList(GrandParent).LTIdx = IdxToBeRemoved Then NodeList(GrandParent).LTIdx = LEAF_NODE Else NodeList(GrandParent).GEIdx = LEAF_NODE End If MarkNodeAsFree IdxToBeRemoved AddTree GEChild, Root AddTree LTChild, Root End Sub
Private Sub AddTree(ByRef IdxToAdd&, ByRef idx&)
If NodeList(IdxToAdd).value < NodeList(idx).value Then If NodeList(idx).LTIdx = LEAF_NODE Then NodeList(idx).LTIdx = IdxToAdd NodeList(IdxToAdd).ParentIdx = idx Else AddTree IdxToAdd, NodeList(idx).LTIdx End If Else If NodeList(idx).GEIdx = LEAF_NODE Then NodeList(idx).GEIdx = IdxToAdd NodeList(IdxToAdd).ParentIdx = idx Else AddTree IdxToAdd, NodeList(idx).GEIdx End If End If End Sub
Private Sub MakeSingleChildRoot(IdxToBeRemoved&) Dim idx&
If NodeList(IdxToBeRemoved).GEIdx = LEAF_NODE Then idx = NodeList(IdxToBeRemoved).LTIdx Else idx = NodeList(IdxToBeRemoved).GEIdx End If NodeList(idx).ParentIdx = ROOT_NODE Root = idx End Sub
Private Sub PointSingleChildToGrandparent(ByRef IdxToBeRemoved&)
Dim ChildIdx As Long, GrandParent&
If NodeList(IdxToBeRemoved).GEIdx = LEAF_NODE Then ChildIdx = NodeList(IdxToBeRemoved).LTIdx Else ChildIdx = NodeList(IdxToBeRemoved).GEIdx End If GrandParent = NodeList(IdxToBeRemoved).ParentIdx If NodeList(GrandParent).GEIdx = IdxToBeRemoved Then NodeList(GrandParent).GEIdx = ChildIdx Else NodeList(GrandParent).LTIdx = ChildIdx End If NodeList(ChildIdx).ParentIdx = GrandParent End Sub
Private Sub Class_Initialize() ReDim NodeList(0) As Node ExpandList INITIAL_NODES m_ChunkSize = ALLOC_AMT End Sub
Private Sub ExpandList(ByVal numEls As Long) Dim ndx As Long, newFreeNdx As Long newFreeNdx = UBound(NodeList) + 1 ReDim Preserve NodeList(UBound(NodeList) + numEls) As Node For ndx = newFreeNdx To UBound(NodeList) NodeList(ndx).GEIdx = ndx + 1 NodeList(ndx).LTIdx = FREE_INDICATOR NodeList(ndx).ParentIdx = -1 NodeList(ndx).Deleteed = False Next NodeList(UBound(NodeList)).GEIdx = FreeStart FreeStart = newFreeNdx End Sub
Sub CheckIndex(ByVal Index As Long) If Index <= 0 Or Index > UBound(NodeList) Then Err.Raise 5 If NodeList(Index).ParentIdx < 0 Then Err.Raise 5 End Sub
Private Function FindHelper(ByRef vKey As Variant, ByRef idx&) As Variant
If idx = LEAF_NODE Then FindHelper = "NOT FOUND" ElseIf vKey = NodeList(idx).value And Not NodeList(idx).Deleteed Then FindHelper = NodeList(idx).value ElseIf vKey < NodeList(idx).value Then FindHelper = FindHelper(vKey, NodeList(idx).LTIdx) Else FindHelper = FindHelper(vKey, NodeList(idx).GEIdx) End If End Function
Private Sub Process(ByRef idx&, ByRef ret$) If idx = LEAF_NODE Or idx = 0 Then Exit Sub End If With NodeList(idx) Process .GEIdx, ret If Not .Deleteed Then ret = ret & ", " & .value End If Process .LTIdx, ret End With End Sub
Private Sub MarkNodeAsFree(newFreeIndx&)
With NodeList(newFreeIndx) .GEIdx = FreeStart .LTIdx = FREE_INDICATOR .ParentIdx = LEAF_NODE .value = FREE_INDICATOR End With FreeStart = newFreeIndx End Sub
Private Function FindIndex(vKey As Variant) As Long
If Root = 0 Then FindIndex = -5 Exit Function End If FindIndex = FindIndexHelper(vKey, Root) End Function
Private Function FindIndexHelper(vKey As Variant, idx&) As Long If idx = LEAF_NODE Then FindIndexHelper = -5 ElseIf vKey = NodeList(idx).value And Not NodeList(idx).Deleteed Then FindIndexHelper = idx ElseIf vKey < NodeList(idx).value Then FindIndexHelper = FindIndexHelper(vKey, NodeList(idx).LTIdx) Else FindIndexHelper = FindIndexHelper(vKey, NodeList(idx).GEIdx) End If End Function
Private Sub AddHelper(ByRef idxAdded&, ByRef idx&) If NodeList(idxAdded).value < NodeList(idx).value Then If NodeList(idx).LTIdx = LEAF_NODE Then NodeList(idx).LTIdx = idxAdded NodeList(idxAdded).ParentIdx = idx Else AddHelper idxAdded, NodeList(idx).LTIdx End If Else If NodeList(idx).GEIdx = LEAF_NODE Then NodeList(idx).GEIdx = idxAdded NodeList(idxAdded).ParentIdx = idx Else AddHelper idxAdded, NodeList(idx).GEIdx End If End If End Sub
Public Property Get Count() As Long Count = m_Count End Property
Public Sub RemoveAll() Root = 0 FreeStart = 0 ReDim NodeList(0) As Node m_Count = 0 End Sub
Private Sub Class_Terminate() RemoveAll End Sub |
|
|
|
Submitted By :
Nayan Patel
(Member Since : 5/26/2004 12:23:06 PM)
|
|
|
Job Description :
He is the moderator of this site and currently working as an independent consultant. He works with VB.net/ASP.net, SQL Server and other MS technologies. He is MCSD.net, MCDBA and MCSE. In his free time he likes to watch funny movies and doing oil painting. |
View all (893) submissions by this author
(Birth Date : 7/14/1981 ) |
|
|