| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  | ! Copyright (C) 2007 Ryan Murphy, Doug Coleman. | 
					
						
							|  |  |  | ! See http://factorcode.org/license.txt for BSD license. | 
					
						
							| 
									
										
										
										
											2007-11-05 12:35:44 -05:00
										 |  |  | USING: kernel math sequences arrays assocs ;
 | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  | IN: heaps | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | <PRIVATE
 | 
					
						
							|  |  |  | TUPLE: heap data ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-05 12:10:26 -05:00
										 |  |  | : <heap> ( class -- heap )
 | 
					
						
							| 
									
										
										
										
											2007-11-05 02:42:37 -05:00
										 |  |  |     >r V{ } clone heap construct-boa r> | 
					
						
							|  |  |  |     construct-delegate ; inline
 | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  | PRIVATE>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TUPLE: min-heap ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-05 02:42:37 -05:00
										 |  |  | : <min-heap> ( -- min-heap ) min-heap <heap> ;
 | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | TUPLE: max-heap ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-05 02:42:37 -05:00
										 |  |  | : <max-heap> ( -- max-heap ) max-heap <heap> ;
 | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | <PRIVATE
 | 
					
						
							| 
									
										
										
										
											2007-11-05 02:42:37 -05:00
										 |  |  | : left ( n -- m ) 2 * 1+ ; inline
 | 
					
						
							|  |  |  | : right ( n -- m ) 2 * 2 + ; inline
 | 
					
						
							|  |  |  | : up ( n -- m ) 1- 2 /i ; inline
 | 
					
						
							|  |  |  | : left-value ( n heap -- obj ) >r left r> nth ; inline
 | 
					
						
							|  |  |  | : right-value ( n heap -- obj ) >r right r> nth ; inline
 | 
					
						
							|  |  |  | : up-value ( n vec -- obj ) >r up r> nth ; inline
 | 
					
						
							|  |  |  | : swap-up ( n vec -- ) >r dup up r> exchange ; inline
 | 
					
						
							|  |  |  | : last-index ( vec -- n ) length 1- ; inline
 | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-05 12:10:26 -05:00
										 |  |  | GENERIC: heap-compare ( pair1 pair2 heap -- ? )
 | 
					
						
							| 
									
										
										
										
											2007-11-05 12:35:44 -05:00
										 |  |  | : (heap-compare) drop [ first ] compare 0 ; inline
 | 
					
						
							| 
									
										
										
										
											2007-11-05 12:10:26 -05:00
										 |  |  | M: min-heap heap-compare (heap-compare) > ;
 | 
					
						
							|  |  |  | M: max-heap heap-compare (heap-compare) < ;
 | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-05 02:42:37 -05:00
										 |  |  | : heap-bounds-check? ( m heap -- ? )
 | 
					
						
							|  |  |  |     heap-data length >= ; inline
 | 
					
						
							| 
									
										
										
										
											2007-11-05 12:35:44 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  | : left-bounds-check? ( m heap -- ? )
 | 
					
						
							| 
									
										
										
										
											2007-11-05 02:42:37 -05:00
										 |  |  |     >r left r> heap-bounds-check? ; inline
 | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : right-bounds-check? ( m heap -- ? )
 | 
					
						
							| 
									
										
										
										
											2007-11-05 02:42:37 -05:00
										 |  |  |     >r right r> heap-bounds-check? ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : up-heap-continue? ( vec heap -- ? )
 | 
					
						
							|  |  |  |     >r [ last-index ] keep [ up-value ] keep peek r> | 
					
						
							|  |  |  |     heap-compare ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : up-heap ( vec heap -- )
 | 
					
						
							|  |  |  |     2dup up-heap-continue?  [ | 
					
						
							|  |  |  |         >r dup last-index [ over swap-up ] keep
 | 
					
						
							|  |  |  |         up 1+ head-slice r> up-heap | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  |     ] [ | 
					
						
							|  |  |  |         2drop
 | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-05 02:42:37 -05:00
										 |  |  | : (child) ( m heap -- n )
 | 
					
						
							|  |  |  |     dupd
 | 
					
						
							|  |  |  |     [ heap-data left-value ] 2keep
 | 
					
						
							|  |  |  |     [ heap-data right-value ] keep heap-compare | 
					
						
							|  |  |  |     [ right ] [ left ] if ;
 | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : child ( m heap -- n )
 | 
					
						
							| 
									
										
										
										
											2007-11-05 02:42:37 -05:00
										 |  |  |     2dup right-bounds-check? [ drop left ] [ (child) ] if ;
 | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : swap-down ( m heap -- )
 | 
					
						
							|  |  |  |     [ child ] 2keep heap-data exchange ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | DEFER: down-heap | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-05 02:42:37 -05:00
										 |  |  | : down-heap-continue? ( heap m heap -- m heap ? )
 | 
					
						
							|  |  |  |     [ heap-data nth ] 2keep child pick
 | 
					
						
							|  |  |  |     dupd [ heap-data nth swapd ] keep heap-compare ;
 | 
					
						
							| 
									
										
										
										
											2007-11-05 12:35:44 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  | : (down-heap) ( m heap -- )
 | 
					
						
							| 
									
										
										
										
											2007-11-05 02:42:37 -05:00
										 |  |  |     2dup down-heap-continue? [ | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  |         -rot [ swap-down ] keep down-heap | 
					
						
							|  |  |  |     ] [ | 
					
						
							|  |  |  |         3drop
 | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : down-heap ( m heap -- )
 | 
					
						
							|  |  |  |     2dup left-bounds-check? [ 2drop ] [ (down-heap) ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | PRIVATE>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-05 12:35:44 -05:00
										 |  |  | : heap-push ( value key heap -- )
 | 
					
						
							|  |  |  |     >r swap 2array r> | 
					
						
							|  |  |  |     [ heap-data push ] keep
 | 
					
						
							|  |  |  |     [ heap-data ] keep
 | 
					
						
							|  |  |  |     up-heap ;
 | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-05 12:35:44 -05:00
										 |  |  | : heap-push-all ( assoc heap -- )
 | 
					
						
							| 
									
										
										
										
											2007-11-05 12:48:22 -05:00
										 |  |  |     [ swapd heap-push ] curry assoc-each ;
 | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-05 12:35:44 -05:00
										 |  |  | : heap-peek ( heap -- value key )
 | 
					
						
							|  |  |  |     heap-data first first2 swap ;
 | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-05 02:42:37 -05:00
										 |  |  | : heap-pop* ( heap -- )
 | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  |     dup heap-data length 1 > [ | 
					
						
							| 
									
										
										
										
											2007-11-05 02:42:37 -05:00
										 |  |  |         [ heap-data pop ] keep
 | 
					
						
							|  |  |  |         [ heap-data set-first ] keep
 | 
					
						
							|  |  |  |         0 swap down-heap | 
					
						
							| 
									
										
										
										
											2007-11-02 15:41:19 -04:00
										 |  |  |     ] [ | 
					
						
							|  |  |  |         heap-data pop*
 | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-05 12:35:44 -05:00
										 |  |  | : heap-pop ( heap -- value key ) dup heap-peek rot heap-pop* ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-05 02:42:37 -05:00
										 |  |  | : heap-empty? ( heap -- ? ) heap-data empty? ;
 | 
					
						
							| 
									
										
										
										
											2007-11-05 12:35:44 -05:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2007-11-05 12:10:26 -05:00
										 |  |  | : heap-length ( heap -- n ) heap-data length ;
 |