-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtree.js
More file actions
271 lines (167 loc) · 3.65 KB
/
tree.js
File metadata and controls
271 lines (167 loc) · 3.65 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
//
// tree.js
//
// tree data structure in javascript
//
var blue = {}
blue.tree = function() {
var pub = {}
// creates a new node
pub.node = function( item ) {
var nod = make.node( item)
return nod
}
// namespace
var make = {}
// create a new node
make.node = function( item ) {
// node
var nod = {}
// item
// "payload" of the node
// assign the provided item property
nod.item = null
if( item )
nod.item = item
// top node
nod.top = null
// prev
nod.prev = null
// next
nod.next = null
// namespace for sub nodes
nod.sub = make.sub( nod )
// removes the node form its tree.
// returns the node.
nod.rip = function() {
if( ! nod.top ) return nod
if( nod.next )
nod.next.prev = nod.prev
if( nod.prev )
nod.prev.next = nod.next
if( nod.top.sub.last == nod )
nod.top.sub.last = nod.prev
if( nod.top.sub.first == nod )
nod.top.sub.first = nod.next
nod.top.sub.n--
nod.top = null
nod.next = null
nod.prev = null
return nod
}
// executes function func on all the tree
// nodes below (recursively)
nod.walk = function( do_on_each ) {
var node = nod.sub.first
while( node ) {
do_on_each( node )
if( node.sub.n > 0 )
node.walk( do_on_each )
node = node.next
}
}
// returns an array with references to all nodes in tree
nod.flat = function() {
var flat = []
var grab = function( node ) {
flat.push( node )
}
nod.walk( grab )
return flat
}
// places nod as prev of nex
// nex must be sub of another.
// returns the inserted node
nod.put_before_of = function( nex ) {
if( ! nex.top )
throw "not valid parameter, method put_before_of: parameter node is not a sub node in a tree"
nod.next = nex
nod.prev = nex.prev
nod.top = nex.top
nex.prev.next = nod
nex.prev = nod
if(nex.top.sub.first == nex)
nex.top.sub.first = nod
nex.top.sub.n++
return nod
}
return nod
}
// namespace for sub operations
make.sub = function( nod ) {
var pub = {}
// the owner node of this
// "sub" namespace
pub.nod = nod
// first and last sub
pub.first = null
pub.last = null
// number of sub nodes
pub.n = 0
// get subnode at index position (0 index)
pub.at = function( index ) {
var pik,i
if( index > pub.n - 1 )
return null
pik = pub.first
for( i=0; i<index; i++ )
pik = pik.next
return pik
}
// add sub node at last position
// returns the added node
pub.add = function( sub ) {
if( pub.last ) {
sub.prev = pub.last
pub.last.next = sub
pub.last = sub
} else {
pub.first = sub
pub.last = sub
}
sub.top = pub.nod
pub.n++
return sub
}
// insert sub node at index position
// returns the inserted node
pub.insert = function( sub, index ) {
var pik
// validate index given
if( index < 0 )
throw "node insert failed, invalid index"
if( index > pub.n )
throw "node insert failed, given index exceeds valid places"
// if insert at last+1, then just add
if( index == pub.n ) {
pub.top.add( sub )
return
}
pik = pub.at( index )
sub.prev = pik.prev
sub.next = pik
// if not inserting at first
if( pik.prev ) {
pik.prev.next = sub
} else {
// inserting as first
pik.top.sub.first = sub
}
pik.prev = sub
sub.top = pub.nod
pub.n++
return sub
}
// executes function "func" on each direct
// sub node (not recursive)
pub.each = function( do_on_each ) {
var node = pub.first
while( node ) {
do_on_each( node )
node = node.next
}
}
return pub
}
return pub
}()