3535 */
3636
3737import {
38- Optional ,
39- assert ,
40- guard ,
38+ Optional ,
39+ assert ,
40+ guard ,
4141} from '@cosmicmind/foundationjs'
4242
4343import {
44- Stackable ,
45- stackIterateFrom ,
46- stackDepth ,
47- Listable ,
48- List ,
49- listCreate ,
50- listIsFirst ,
51- listIsLast ,
52- listInsert ,
53- listAppend ,
54- listRemove ,
55- listRemoveFirst ,
56- listInsertBefore ,
57- listInsertAfter ,
58- listIterateFromFirst ,
44+ Stackable ,
45+ stackIterateFrom ,
46+ stackDepth ,
47+ Listable ,
48+ List ,
49+ listCreate ,
50+ listIsFirst ,
51+ listIsLast ,
52+ listInsert ,
53+ listAppend ,
54+ listRemove ,
55+ listRemoveFirst ,
56+ listInsertBefore ,
57+ listInsertAfter ,
58+ listIterateFromFirst ,
5959} from '@/structures'
6060
6161import {
62- SentinelNode ,
62+ SentinelNode ,
6363} from '@/utils'
6464
6565export type Tree = Listable & Stackable & {
66- parent ?: Tree
67- next ?: Tree
68- previous ?: Tree
69- children : List < Tree >
70- size : number
66+ parent ?: Tree
67+ next ?: Tree
68+ previous ?: Tree
69+ children : List < Tree >
70+ size : number
7171}
7272
7373export const TreeCompareFn = < T extends Tree > ( a : T , b : T ) : number => a === b ? 0 : a > b ? 1 : - 1
7474
7575export const treeCreate = < T extends Tree > ( props ?: Omit < T , keyof Tree > ) : T => ( {
76- ...( props ?? { } ) as T ,
77- parent : SentinelNode ,
78- next : SentinelNode ,
79- previous : SentinelNode ,
80- children : listCreate < T > ( ) ,
81- size : 1 ,
76+ ...( props ?? { } ) as T ,
77+ parent : SentinelNode ,
78+ next : SentinelNode ,
79+ previous : SentinelNode ,
80+ children : listCreate < T > ( ) ,
81+ size : 1 ,
8282} )
8383
8484/**
8585 * @performance O(1)
8686 */
8787export function treeInsertChild < T extends Tree > ( parent : T , node : T ) : void {
88- node . parent = parent
89- listInsert ( parent . children , node )
90- treeIncreaseSize ( parent , node . size )
88+ node . parent = parent
89+ listInsert ( parent . children , node )
90+ treeIncreaseSize ( parent , node . size )
9191}
9292
9393/**
9494 * @performance O(1)
9595 */
9696export function treeInsertChildBefore < T extends Tree > ( parent : T , node : T , before : T , compare = TreeCompareFn < T > ) : void {
97- node . parent = parent
98- listInsertBefore ( parent . children as List < T > , node , before , compare )
99- treeIncreaseSize ( parent , node . size )
97+ node . parent = parent
98+ listInsertBefore ( parent . children as List < T > , node , before , compare )
99+ treeIncreaseSize ( parent , node . size )
100100}
101101
102102/**
103103 * @performance O(1)
104104 */
105105export function treeInsertChildAfter < T extends Tree > ( parent : T , node : T , after : T , compare = TreeCompareFn < T > ) : void {
106- node . parent = parent
107- listInsertAfter ( parent . children as List < T > , node , after , compare )
108- treeIncreaseSize ( parent , node . size )
106+ node . parent = parent
107+ listInsertAfter ( parent . children as List < T > , node , after , compare )
108+ treeIncreaseSize ( parent , node . size )
109109}
110110
111111/**
112112 * @performance O(1)
113113 */
114114export function treeAppendChild < T extends Tree > ( parent : T , node : T ) : void {
115- node . parent = parent
116- listAppend ( parent . children , node )
117- treeIncreaseSize ( parent , node . size )
115+ node . parent = parent
116+ listAppend ( parent . children , node )
117+ treeIncreaseSize ( parent , node . size )
118118}
119119
120120export function treeRemove < T extends Tree > ( node : T , compare = TreeCompareFn < T > ) : void {
121- const parent = node . parent as Optional < T >
122- if ( guard < T > ( parent ) ) {
123- listRemove ( parent . children as List < T > , node , compare )
124- treeDecreaseSize ( parent , node . size )
125- node . parent = SentinelNode
126- }
121+ const parent = node . parent as Optional < T >
122+ if ( guard < T > ( parent ) ) {
123+ listRemove ( parent . children as List < T > , node , compare )
124+ treeDecreaseSize ( parent , node . size )
125+ node . parent = SentinelNode
126+ }
127127}
128128
129129/**
130130 * @performance O(n)
131131 */
132132export const treeDepth = < T extends Tree > ( root : T ) : ReturnType < typeof stackDepth > =>
133- stackDepth ( root )
133+ stackDepth ( root )
134134
135135/**
136136 * @performance O(1)
137137 */
138138export function treeIsRoot < T extends Tree > ( node : T ) : boolean {
139- return SentinelNode === node . parent
139+ return SentinelNode === node . parent
140140}
141141
142142/**
143143 * @performance O(1)
144144 */
145145export function treeIsLeaf < T extends Tree > ( node : T ) : boolean {
146- return 0 === node . children . count
146+ return 0 === node . children . count
147147}
148148
149149/**
150150 * @performance O(1)
151151 */
152152export function treeIsChild < T extends Tree > ( parent : T , node : T , compare = TreeCompareFn < T > ) : boolean {
153- return guard < T > ( node . parent ) && 0 === compare ( node . parent , parent )
153+ return guard < T > ( node . parent ) && 0 === compare ( node . parent , parent )
154154}
155155
156156/**
157157 * @performance O(1)
158158 */
159159export function treeIsFirstChild < T extends Tree > ( parent : T , node : T , compare = TreeCompareFn < T > ) : boolean {
160- return listIsFirst ( parent . children as List < T > , node , compare )
160+ return listIsFirst ( parent . children as List < T > , node , compare )
161161}
162162
163163/**
164164 * @performance O(1)
165165 */
166166export function treeIsLastChild < T extends Tree > ( parent : T , node : T , compare = TreeCompareFn < T > ) : boolean {
167- return listIsLast ( parent . children as List < T > , node , compare )
167+ return listIsLast ( parent . children as List < T > , node , compare )
168168}
169169
170170/**
171171 * @performance O(1)
172172 */
173173export function treeIsOnlyChild < T extends Tree > ( parent : T , node : T , compare = TreeCompareFn < T > ) : boolean {
174- return listIsFirst ( parent . children as List < T > , node , compare ) && listIsLast ( parent . children as List < T > , node , compare )
174+ return listIsFirst ( parent . children as List < T > , node , compare ) && listIsLast ( parent . children as List < T > , node , compare )
175175}
176176
177177/**
178178 * @performance O(h) where h = height of Tree
179179 */
180180export function treeIsChildDeep < T extends Tree > ( parent : T , node : T , compare = TreeCompareFn < T > ) : boolean {
181- let n = node . parent
182- while ( guard < T > ( n ) ) {
183- if ( 0 === compare ( n , parent ) ) {
184- return true
181+ let n = node . parent
182+ while ( guard < T > ( n ) ) {
183+ if ( 0 === compare ( n , parent ) ) {
184+ return true
185+ }
186+ n = n . parent
185187 }
186- n = n . parent
187- }
188- return false
188+ return false
189189}
190190
191191/**
192192 * @performance O(n)
193193 */
194194export function treeIncreaseSize < T extends Tree > ( root : T , size : number ) : void {
195- assert ( 0 < size , 'size must be greater than 0' )
196- for ( const node of stackIterateFrom ( root ) ) {
197- node . size += size
198- }
195+ assert ( 0 < size , 'size must be greater than 0' )
196+ for ( const node of stackIterateFrom ( root ) ) {
197+ node . size += size
198+ }
199199}
200200
201201/**
202202 * @performance O(n)
203203 */
204204export function treeDecreaseSize < T extends Tree > ( root : T , size : number ) : void {
205- assert ( 0 < size , 'size must be greater than 0' )
206- for ( const n of stackIterateFrom ( root ) ) {
207- n . size -= size
208- }
205+ assert ( 0 < size , 'size must be greater than 0' )
206+ for ( const n of stackIterateFrom ( root ) ) {
207+ n . size -= size
208+ }
209209}
210210
211211/**
212212 * @performance O(n)
213213 */
214214export function * depthFirstIterator < T extends Tree > ( root : T ) : IterableIterator < T > {
215- yield root
216- for ( const n of listIterateFromFirst ( root . children as List < T > ) ) {
217- yield * depthFirstIterator ( n )
218- }
215+ yield root
216+ for ( const n of listIterateFromFirst ( root . children as List < T > ) ) {
217+ yield * depthFirstIterator ( n )
218+ }
219219}
220220
221221/**
222222 * @performance O(n)
223223 */
224224export function * breadthFirstIterator < T extends Tree > ( root : T ) : IterableIterator < T > {
225- const queue = listCreate < T > ( )
226- listAppend ( queue , { ...root } )
225+ const queue = listCreate < T > ( )
226+ listAppend ( queue , { ...root } )
227227
228- while ( 0 < queue . count ) {
229- const node = listRemoveFirst ( queue ) as T
228+ while ( 0 < queue . count ) {
229+ const node = listRemoveFirst ( queue ) as T
230230
231- yield node
231+ yield node
232232
233- for ( const q of listIterateFromFirst ( node . children as List < T > ) ) {
234- listAppend ( queue , { ...q } )
233+ for ( const q of listIterateFromFirst ( node . children as List < T > ) ) {
234+ listAppend ( queue , { ...q } )
235+ }
235236 }
236- }
237237}
238238
239239/**
240240 * @performance O(n)
241241 */
242242export function treeQuery < T extends Tree > ( root : T , ...fn : ( ( node : T ) => boolean ) [ ] ) : Set < T > {
243- const r = new Set < T > ( )
244- loop: for ( const node of depthFirstIterator ( root ) ) {
245- for ( const f of fn ) {
246- if ( f ( node ) ) {
247- continue
248- }
249- continue loop
243+ const r = new Set < T > ( )
244+ loop: for ( const node of depthFirstIterator ( root ) ) {
245+ for ( const f of fn ) {
246+ if ( f ( node ) ) {
247+ continue
248+ }
249+ continue loop
250+ }
251+ r . add ( node )
250252 }
251- r . add ( node )
252- }
253- return r
253+ return r
254254}
0 commit comments