map.monkey2 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710
  1. Namespace std.collections
  2. #rem monkeydoc Convenience type alias for Map\<Int,V\>.
  3. #end
  4. Alias IntMap<V>:Map<Int,V>
  5. #rem monkeydoc Convenience type alias for Map\<Float,V\>.
  6. #end
  7. Alias FloatMap<V>:Map<Float,V>
  8. #rem monkeydoc Convenience type alias for Map\<String,V\>.
  9. #end
  10. Alias StringMap<V>:Map<String,V>
  11. #rem monkeydoc The Map class provides support for associative maps.
  12. A map is a container style object that provides a mechanism for associating 'key' objects with 'value' objects.
  13. This is done using an internal node object that contains a reference to both a key and a value, along with information about the node'
  14. s location within the map.
  15. Each key in a map occurs exactly once - a map cannot contain multiple equivalent keys.
  16. Maps can handle inserting, removing and finding keys in 'O(log2)' time. That is, the time needed to insert, remove or find a key is proportional to log2 of the number of items in the map.
  17. #end
  18. Class Map<K,V>
  19. #rem monkeydoc The map Node class.
  20. #end
  21. Class Node
  22. #rem monkeydoc Gets the key contained in the node.
  23. @return The node's key.
  24. #end
  25. Property Key:K()
  26. Return _key
  27. End
  28. #rem monkeydoc Gets the value contained in the node.
  29. @return The node's value.
  30. #end
  31. Property Value:V()
  32. Return _value
  33. Setter( value:V )
  34. _value=value
  35. End
  36. Private
  37. Enum Color
  38. Red
  39. Black
  40. End
  41. Field _key:K
  42. Field _value:V
  43. Field _color:Color
  44. Field _left:Node
  45. Field _right:Node
  46. Field _parent:Node
  47. Method New( key:K,value:V,color:Color,parent:Node )
  48. _key=key
  49. _value=value
  50. _color=color
  51. _parent=parent
  52. End
  53. Method Count:Int( n:Int )
  54. If _left n=_left.Count( n )
  55. If _right n=_right.Count( n )
  56. Return n+1
  57. End
  58. Method NextNode:Node()
  59. If _right
  60. Local node:=_right
  61. While node._left
  62. node=node._left
  63. Wend
  64. Return node
  65. Endif
  66. Local node:=Self,parent:=_parent
  67. While parent And node=parent._right
  68. node=parent
  69. parent=parent._parent
  70. Wend
  71. Return parent
  72. End
  73. Method PrevNode:Node()
  74. If _left
  75. Local node:=_left
  76. While node._right
  77. node=node._right
  78. Wend
  79. Return node
  80. Endif
  81. Local node:=Self,parent:=_parent
  82. While parent And node=parent._left
  83. node=parent
  84. parent=parent._parent
  85. Wend
  86. Return parent
  87. End
  88. Method Copy:Node( parent:Node )
  89. Local node:=New Node( _key,_value,_color,parent )
  90. If _left node._left=_left.Copy( node )
  91. If _right node._right=_right.Copy( node )
  92. Return node
  93. End
  94. End
  95. Struct Iterator
  96. Property AtEnd:Bool()
  97. Return _node=Null
  98. End
  99. Property Valid:Bool()
  100. Return _node
  101. End
  102. Property Current:Node()
  103. Return _node
  104. End
  105. Method Bump()
  106. _node=_node.NextNode()
  107. End
  108. Private
  109. Field _node:Node
  110. Method New( node:Node )
  111. _node=node
  112. End
  113. End
  114. Struct KeyIterator
  115. Property AtEnd:Bool()
  116. Return _node=Null
  117. End
  118. Property Valid:Bool()
  119. Return _node
  120. End
  121. Property Current:K()
  122. Return _node._key
  123. End
  124. Method Bump()
  125. _node=_node.NextNode()
  126. End
  127. Private
  128. Field _node:Node
  129. Method New( node:Node )
  130. _node=node
  131. End
  132. End
  133. Struct ValueIterator
  134. Property AtEnd:Bool()
  135. Return _node=Null
  136. End
  137. Property Valid:Bool()
  138. Return _node
  139. End
  140. Property Current:V()
  141. Return _node._value
  142. End
  143. Method Bump()
  144. _node=_node.NextNode()
  145. End
  146. Private
  147. Field _node:Node
  148. Method New( node:Node )
  149. _node=node
  150. End
  151. End
  152. Struct MapKeys
  153. Method All:KeyIterator()
  154. Return New KeyIterator( _map.FirstNode() )
  155. End
  156. Private
  157. Field _map:Map
  158. Method New( map:Map )
  159. _map=map
  160. End
  161. End
  162. Struct MapValues
  163. Method All:ValueIterator()
  164. Return New ValueIterator( _map.FirstNode() )
  165. End
  166. Private
  167. Field _map:Map
  168. Method New( map:Map )
  169. _map=map
  170. End
  171. End
  172. #rem monkeydoc Creates a new empty map.
  173. #end
  174. Method New()
  175. End
  176. #rem monkeydoc Gets a node iterator.
  177. #end
  178. Method All:Iterator()
  179. Return New Iterator( FirstNode() )
  180. End
  181. #rem monkeydoc Gets a view of the map's keys.
  182. The returned value can be used with an Eachin loop to iterate over the map's keys.
  183. @return A MapKeys object.
  184. #end
  185. Property Keys:MapKeys()
  186. Return New MapKeys( Self )
  187. End
  188. #rem monkeydoc Gets a view of the map's values.
  189. The returned value can be used with an Eachin loop to iterate over the map's values.
  190. @return A MapValues object.
  191. #end
  192. Property Values:MapValues()
  193. Return New MapValues( Self )
  194. End
  195. #rem monkeydocs Copies the map.
  196. @return A new map.
  197. #end
  198. Method Copy:Map()
  199. Local root:Node
  200. If _root root=_root.Copy( Null )
  201. Return New Map( root )
  202. End
  203. #rem monkeydoc Removes all keys from the map.
  204. #end
  205. Method Clear()
  206. _root=Null
  207. End
  208. #rem monkeydoc Gets the number of keys in the map.
  209. @return The number of keys in the map.
  210. #end
  211. Method Count:Int()
  212. If Not _root Return 0
  213. Return _root.Count( 0 )
  214. End
  215. #rem monkeydoc Checks if the map is empty.
  216. @return True if the map is empty.
  217. #end
  218. Property Empty:Bool()
  219. Return _root=Null
  220. End
  221. #rem monkeydoc Checks if the map contains a given key.
  222. @param key The key to check for.
  223. @return True if the map contains the key.
  224. #end
  225. Method Contains:Bool( key:K )
  226. Return FindNode( key )<>Null
  227. End
  228. #rem monkeydoc Sets the value associated with a key in the map.
  229. If the map does not contain `key`, a new key/value node is added and true is returned.
  230. If the map already contains `key`, its associated value is updated and false is returned.
  231. This operator functions identically to Set.
  232. @param key The key.
  233. @param value The value.
  234. @return True if a new node was added to the map.
  235. #end
  236. Operator[]=( key:K,value:V )
  237. Set( key,value )
  238. End
  239. #rem monkeydoc Gets the value associated with a key in the map.
  240. @param key The key.
  241. @return The value associated with `key`, or null if `key` is not in the map.
  242. #end
  243. Operator[]:V( key:K )
  244. Local node:=FindNode( key )
  245. If Not node Return Null
  246. Return node._value
  247. End
  248. #rem monkeydoc Sets the value associated with a key in the map.
  249. If the map does not contain `key`, a new key/value node is added to the map and true is returned.
  250. If the map already contains `key`, its associated value is updated and false is returned.
  251. @param key The key.
  252. @param value The value.
  253. @return True if a new node was added to the map, false if an existing node was updated.
  254. #end
  255. Method Set:Bool( key:K,value:V )
  256. If Not _root
  257. _root=New Node( key,value,Node.Color.Red,Null )
  258. Return True
  259. Endif
  260. Local node:=_root,parent:Node,cmp:Int
  261. While node
  262. parent=node
  263. cmp=key<=>node._key
  264. If cmp>0
  265. node=node._right
  266. Else If cmp<0
  267. node=node._left
  268. Else
  269. node._value=value
  270. Return False
  271. Endif
  272. Wend
  273. node=New Node( key,value,Node.Color.Red,parent )
  274. If cmp>0 parent._right=node Else parent._left=node
  275. InsertFixup( node )
  276. Return True
  277. End
  278. #rem monkeydoc Adds a new key/value pair to a map.
  279. If the map does not contain `key', a new key/value node is created and true is returned.
  280. If the map already contains `key`, nothing happens and false is returned.
  281. @param key The key.
  282. @param value The value.
  283. @return True if a new node was added to the map, false if the map was not modified.
  284. #end
  285. Method Add:Bool( key:K,value:V )
  286. If Not _root
  287. _root=New Node( key,value,Node.Color.Red,Null )
  288. Return True
  289. Endif
  290. Local node:=_root,parent:Node,cmp:Int
  291. While node
  292. parent=node
  293. cmp=key<=>node._key
  294. If cmp>0
  295. node=node._right
  296. Else If cmp<0
  297. node=node._left
  298. Else
  299. Return False
  300. Endif
  301. Wend
  302. node=New Node( key,value,Node.Color.Red,parent )
  303. If cmp>0 parent._right=node Else parent._left=node
  304. InsertFixup( node )
  305. Return True
  306. End
  307. #rem monkeydoc Updates the value associated with a key in the map.
  308. If the map does not contain `key', nothing happens and false is returned.
  309. If the map already contains `key`, its associated value is updated and true is returned.
  310. @param key The key.
  311. @param value The value.
  312. @return True if the value associated with `key` was updated, false if the map was not modified.
  313. #end
  314. Method Update:Bool( key:K,value:V )
  315. Local node:=FindNode( key )
  316. If Not node Return False
  317. node._value=value
  318. Return True
  319. End
  320. #rem monkeydoc Gets the value associated with a key in the map.
  321. @param key The key.
  322. @return The value associated with the key, or null if the key is not in the map.
  323. #end
  324. Method Get:V( key:K )
  325. Local node:=FindNode( key )
  326. If node Return node._value
  327. Return Null
  328. End
  329. #rem monkeydoc Removes a key from the map.
  330. @param key The key to remove.
  331. @return True if the key was removed, or false if the key is not in the map.
  332. #end
  333. Method Remove:Bool( key:K )
  334. Local node:=FindNode( key )
  335. If Not node Return False
  336. RemoveNode( node )
  337. Return True
  338. End
  339. Private
  340. Field _root:Node
  341. Method New( root:Node )
  342. _root=root
  343. End
  344. Method FirstNode:Node()
  345. If Not _root Return Null
  346. Local node:=_root
  347. While node._left
  348. node=node._left
  349. Wend
  350. Return node
  351. End
  352. Method LastNode:Node()
  353. If Not _root Return Null
  354. Local node:=_root
  355. While node._right
  356. node=node._right
  357. Wend
  358. Return node
  359. End
  360. Method FindNode:Node( key:K )
  361. Local node:=_root
  362. While node
  363. Local cmp:=key<=>node._key
  364. If cmp>0
  365. node=node._right
  366. Else If cmp<0
  367. node=node._left
  368. Else
  369. Return node
  370. Endif
  371. Wend
  372. Return Null
  373. End
  374. Method RemoveNode( node:Node )
  375. Local splice:Node,child:Node
  376. If Not node._left
  377. splice=node
  378. child=node._right
  379. Else If Not node._right
  380. splice=node
  381. child=node._left
  382. Else
  383. splice=node._left
  384. While splice._right
  385. splice=splice._right
  386. Wend
  387. child=splice._left
  388. node._key=splice._key
  389. node._value=splice._value
  390. Endif
  391. Local parent:=splice._parent
  392. If child
  393. child._parent=parent
  394. Endif
  395. If Not parent
  396. _root=child
  397. Return
  398. Endif
  399. If splice=parent._left
  400. parent._left=child
  401. Else
  402. parent._right=child
  403. Endif
  404. If splice._color=Node.Color.Black
  405. DeleteFixup( child,parent )
  406. Endif
  407. End
  408. Method RotateLeft( node:Node )
  409. Local child:=node._right
  410. node._right=child._left
  411. If child._left
  412. child._left._parent=node
  413. Endif
  414. child._parent=node._parent
  415. If node._parent
  416. If node=node._parent._left
  417. node._parent._left=child
  418. Else
  419. node._parent._right=child
  420. Endif
  421. Else
  422. _root=child
  423. Endif
  424. child._left=node
  425. node._parent=child
  426. End
  427. Method RotateRight( node:Node )
  428. Local child:=node._left
  429. node._left=child._right
  430. If child._right
  431. child._right._parent=node
  432. Endif
  433. child._parent=node._parent
  434. If node._parent
  435. If node=node._parent._right
  436. node._parent._right=child
  437. Else
  438. node._parent._left=child
  439. Endif
  440. Else
  441. _root=child
  442. Endif
  443. child._right=node
  444. node._parent=child
  445. End
  446. Method InsertFixup( node:Node )
  447. While node._parent And node._parent._color=Node.Color.Red And node._parent._parent
  448. If node._parent=node._parent._parent._left
  449. Local uncle:=node._parent._parent._right
  450. If uncle And uncle._color=Node.Color.Red
  451. node._parent._color=Node.Color.Black
  452. uncle._color=Node.Color.Black
  453. uncle._parent._color=Node.Color.Red
  454. node=uncle._parent
  455. Else
  456. If node=node._parent._right
  457. node=node._parent
  458. RotateLeft( node )
  459. Endif
  460. node._parent._color=Node.Color.Black
  461. node._parent._parent._color=Node.Color.Red
  462. RotateRight( node._parent._parent )
  463. Endif
  464. Else
  465. Local uncle:=node._parent._parent._left
  466. If uncle And uncle._color=Node.Color.Red
  467. node._parent._color=Node.Color.Black
  468. uncle._color=Node.Color.Black
  469. uncle._parent._color=Node.Color.Red
  470. node=uncle._parent
  471. Else
  472. If node=node._parent._left
  473. node=node._parent
  474. RotateRight( node )
  475. Endif
  476. node._parent._color=Node.Color.Black
  477. node._parent._parent._color=Node.Color.Red
  478. RotateLeft( node._parent._parent )
  479. Endif
  480. Endif
  481. Wend
  482. _root._color=Node.Color.Black
  483. End
  484. Method DeleteFixup( node:Node,parent:Node )
  485. While node<>_root And (Not node Or node._color=Node.Color.Black )
  486. If node=parent._left
  487. Local sib:=parent._right
  488. If sib._color=Node.Color.Red
  489. sib._color=Node.Color.Black
  490. parent._color=Node.Color.Red
  491. RotateLeft( parent )
  492. sib=parent._right
  493. Endif
  494. If (Not sib._left Or sib._left._color=Node.Color.Black) And (Not sib._right Or sib._right._color=Node.Color.Black)
  495. sib._color=Node.Color.Red
  496. node=parent
  497. parent=parent._parent
  498. Else
  499. If Not sib._right Or sib._right._color=Node.Color.Black
  500. sib._left._color=Node.Color.Black
  501. sib._color=Node.Color.Red
  502. RotateRight( sib )
  503. sib=parent._right
  504. Endif
  505. sib._color=parent._color
  506. parent._color=Node.Color.Black
  507. sib._right._color=Node.Color.Black
  508. RotateLeft( parent )
  509. node=_root
  510. Endif
  511. Else
  512. Local sib:=parent._left
  513. If sib._color=Node.Color.Red
  514. sib._color=Node.Color.Black
  515. parent._color=Node.Color.Red
  516. RotateRight( parent )
  517. sib=parent._left
  518. Endif
  519. If (Not sib._right Or sib._right._color=Node.Color.Black) And (Not sib._left Or sib._left._color=Node.Color.Black)
  520. sib._color=Node.Color.Red
  521. node=parent
  522. parent=parent._parent
  523. Else
  524. If Not sib._left Or sib._left._color=Node.Color.Black
  525. sib._right._color=Node.Color.Black
  526. sib._color=Node.Color.Red
  527. RotateLeft( sib )
  528. sib=parent._left
  529. Endif
  530. sib._color=parent._color
  531. parent._color=Node.Color.Black
  532. sib._left._color=Node.Color.Black
  533. RotateRight( parent )
  534. node=_root
  535. Endif
  536. Endif
  537. Wend
  538. If node node._color=Node.Color.Black
  539. End
  540. End