map.monkey2 13 KB

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