Welcome to the CHICKEN Scheme pasting service

binary-heap2 added by megane on Wed Jun 22 16:54:46 2011

Example:
-------
(include "binary_heap2")
(import (prefix binary-heap2 heap:))

(let [(h (heap:make-binary-heap initial-size: 1))]
  (print h)
  (heap:insert h 10 'foo)
  (heap:insert h 100 'bar)
  (print h)
  (print (heap:extract-max h))
  (print (heap:heap-max h))
  (print h))

Output:
------
#,(bin-heap size: 0 capacity: 1)
#,(bin-heap size: 2 capacity: 2)
(100 . bar)
(10 . foo)
#,(bin-heap size: 1 capacity: 2)

(let [(h (heap:make-binary-heap initial-size: 1 more?-and-min-key: (list < +inf)))]
  (print h)
  (heap:insert h 10 'foo)
  (heap:insert h 100 'bar)
  (print h)
  (print (heap:extract-max h))
  (print (heap:heap-max h))
  (print h))

Output:
------
#,(bin-heap size: 1 capacity: 2)
#,(bin-heap size: 0 capacity: 1)
#,(bin-heap size: 2 capacity: 2)
(10 . foo)
(100 . bar)
#,(bin-heap size: 1 capacity: 2)

(module
 binary-heap2 ;; There already exists an egg with the name binary-heap
 (make-binary-heap
  insert
  heap-size
  heap-max
  extract-max)
 
 (import chicken scheme)
 (import extras)

 ;; The heap is stored in a vector where the nodes are
 ;; cons cells. The car is the key of the node and the value
 ;; is in cdr.
 ;; The implementation follows CLRS pretty closely.
 
 (define-record bin-heap
   size
   array
   more?
   min-key)
 
 (define-record-printer (bin-heap x out)
   (fprintf out "#,(bin-heap size: ~S capacity: ~S)"
	    (bin-heap-size x)
	    (vector-length (bin-heap-array x))))

 (define *growth-factor* 2)

 (define-syntax get-key
   (lambda (e r c)
     `(car (vector-ref ,(cadr e) ,(caddr e)))))

 (define-syntax set-key
   (lambda (e r c)
     `(set-car! (vector-ref ,(cadr e) ,(caddr e)) ,(cadddr e))))

 (define-syntax get-val
   (lambda (e r c)
     `(cdr (vector-ref ,(cadr e) ,(caddr e)))))

 (define-syntax set-val
   (lambda (e r c)
     `(set-cdr! (vector-ref ,(cadr e) ,(caddr e)) ,(cadddr e))))

 (define-syntax parent
   (lambda (e r c)
     `(,(r 'arithmetic-shift) ,(cadr e) -1)))

 (define-syntax left
   (lambda (e r c)
     `(,(r 'arithmetic-shift) ,(cadr e) 1)))

 (define-syntax right
   (lambda (e r c)
     `(,(r 'add1) (,(r 'arithmetic-shift) ,(cadr e) 1))))

 (define-syntax swap
   (lambda (e r c)
     (let [(array (cadr e))
	   (i (caddr e))
	   (j (cadddr e))]
       `(let [(x (vector-ref ,array ,i))]
	  (vector-set! ,array
		       ,i (vector-ref ,array ,j))
	  (vector-set! ,array
		       ,j x)))))

 (define (init-array array start end)
   (do [(i start (add1 i))]
	((> i end) array)
      (vector-set! array i (cons #f #f))))

 (define (make-binary-heap #!key (initial-size 32)
			   (more?-and-min-key (list > -inf))) 
   (make-bin-heap 0
		  (init-array (make-vector initial-size) 0 (sub1 initial-size))
		  (car more?-and-min-key)
		  (cadr more?-and-min-key)))

 (define (max-heapify array size i more?)
   (let [(l (left i))
	 (r (right i))
	 (largest i)]
     (if (and (> size l)
	      (more? (get-key array l)
		     (get-key array largest)))
	 (set! largest l))
     (if (and (> size r)
	      (more? (get-key array r)
		     (get-key array largest)))
	 (set! largest r))
     (if (not (= i largest))
	 (begin
	   (swap array largest i)
	   (max-heapify array size largest more?)))))

 (define (heap-size heap)
   (bin-heap-size heap))

 (define (heap-max heap)
   (vector-ref (bin-heap-array heap) 0))

 (define (extract-max heap)
   (let [(x (vector-ref (bin-heap-array heap) 0))]
     (bin-heap-size-set! heap (sub1 (bin-heap-size heap)))
     (swap (bin-heap-array heap) 0 (bin-heap-size heap))
     (max-heapify (bin-heap-array heap) (bin-heap-size heap) 0 (bin-heap-more? heap))
     x))

 
 (define (heap-increase-key array i key more?)
   (if (more? (get-key array i) key)
       (error heap-increase-key "New key was smaller than the old one."))
   (set-key array i key)
   (let loop []
     (if (and (< 0 i)
	      (more? (get-key array i)
		     (get-key array (parent i))))
	 (begin
	   (swap array i (parent i))
	   (set! i (parent i))
	   (loop)))))

 (define (grow-heap heap)
   (let [(last-i (vector-length (bin-heap-array heap)))
	 (old-v (bin-heap-array heap))
	 (new-v (make-vector (* *growth-factor*
				 (vector-length (bin-heap-array heap)))))]
     (init-array new-v (vector-length old-v) (sub1 (vector-length new-v)))
     (do [(i 0 (add1 i))]
	 ((= i last-i)
	  (bin-heap-array-set! heap new-v))
       (vector-set! new-v i (vector-ref old-v i)))))

 (define (insert heap key val)
   (if (> (vector-length (bin-heap-array heap))
	  (bin-heap-size heap))
       (begin
	 (set-key (bin-heap-array heap) (bin-heap-size heap) (bin-heap-min-key heap))
	 (set-val (bin-heap-array heap) (bin-heap-size heap) val)
	 (heap-increase-key (bin-heap-array heap)
			    (bin-heap-size heap)
			    key
			    (bin-heap-more? heap))
	 (bin-heap-size-set! heap (add1 (bin-heap-size heap))))
       (begin
	 (grow-heap heap)
	 (insert heap key val)))))

Your annotation:

Enter a new annotation:

Your nick:
The title of your paste:
Your paste (mandatory) :
Which egg provides `hash-table-ref'?
Visually impaired? Let me spell it for you (wav file) download WAV