KVV and balancing.
This commit is contained in:
parent
7370cea951
commit
901d2f7398
1 changed files with 100 additions and 5 deletions
105
src/util-bst.scm
105
src/util-bst.scm
|
@ -16,12 +16,21 @@
|
||||||
|
|
||||||
bst-set
|
bst-set
|
||||||
bst-remove
|
bst-remove
|
||||||
|
;; bst-update
|
||||||
|
|
||||||
;;bst->kvv
|
bst-keys
|
||||||
;;kvv->bst
|
|
||||||
;;kvv-filter
|
|
||||||
|
|
||||||
;;bst-balance
|
bst->kvv
|
||||||
|
kvv->bst
|
||||||
|
kvv-filter
|
||||||
|
|
||||||
|
bst-balance
|
||||||
|
|
||||||
|
;; bst-find-pair
|
||||||
|
;; bst-filter-pairs
|
||||||
|
|
||||||
|
;; bst-map-list
|
||||||
|
;; bst-map-dict
|
||||||
|
|
||||||
util-bst-tests!
|
util-bst-tests!
|
||||||
)
|
)
|
||||||
|
@ -213,6 +222,79 @@
|
||||||
new-root
|
new-root
|
||||||
(- (bst-count bst) sub-count))))))
|
(- (bst-count bst) sub-count))))))
|
||||||
|
|
||||||
|
;; Unique tag for static vector representation that retains type info
|
||||||
|
(define TAG-KVV (make-tag kvv))
|
||||||
|
|
||||||
|
;; Iterates over given BST and passes the KV pairs to given proc
|
||||||
|
(define (bst-iter-kv bst proc)
|
||||||
|
(let-comparators
|
||||||
|
(EQ? <? bst)
|
||||||
|
(let loop ((n (bst-root bst)))
|
||||||
|
(when n
|
||||||
|
(loop (bst-node-left n))
|
||||||
|
(proc (bst-node-kv n))
|
||||||
|
(loop (bst-node-right n))))))
|
||||||
|
|
||||||
|
|
||||||
|
(define/doc (bst-keys bst)
|
||||||
|
("Returns all the keys contained in given dictionary.")
|
||||||
|
(let ((res '()))
|
||||||
|
(bst-iter-kv bst
|
||||||
|
(lambda (k v)
|
||||||
|
(set! res (cons k res))))
|
||||||
|
(reverse res)))
|
||||||
|
|
||||||
|
;; Converts BST to KVV
|
||||||
|
(define (bst->kvv bst)
|
||||||
|
(let ((vec (make-vector (bst-count bst)))
|
||||||
|
(idx 0))
|
||||||
|
(bst-iter-kv bst
|
||||||
|
(lambda (kv)
|
||||||
|
(vector-set! vec idx kv)
|
||||||
|
(set! idx (add1 idx))))
|
||||||
|
(cons TAG-KVV
|
||||||
|
(cons vec
|
||||||
|
(cddr bst)))))
|
||||||
|
|
||||||
|
;; Converts a vector of key-value cons cells to BST dictionary
|
||||||
|
(define (kvv->bst kvv)
|
||||||
|
(let* ((vec (cadr kvv))
|
||||||
|
(count (vector-length vec)))
|
||||||
|
(cons TAG-BST
|
||||||
|
(cons (cons (let loop ((s 0)
|
||||||
|
(e count))
|
||||||
|
(if (= s e)
|
||||||
|
#f
|
||||||
|
(let* ((c (- e s))
|
||||||
|
(h (quotient c 2))
|
||||||
|
(m (+ s h))
|
||||||
|
(kv (vector-ref vec m)))
|
||||||
|
(cons kv
|
||||||
|
(cons (loop s m)
|
||||||
|
(loop (add1 m) e))))))
|
||||||
|
count)
|
||||||
|
(cddr kvv)))))
|
||||||
|
|
||||||
|
;; Returns KVV that contains only KV pairs matching pred?
|
||||||
|
(define (kvv-filter kvv pred?)
|
||||||
|
(cons (car kvv)
|
||||||
|
(cons (apply vector
|
||||||
|
(let ((vec (cadr kvv)))
|
||||||
|
(let loop ((idx (sub1 (vector-length vec)))
|
||||||
|
(res '()))
|
||||||
|
(if (< idx 0)
|
||||||
|
res
|
||||||
|
(let ((kv (vector-ref vec idx)))
|
||||||
|
(loop (if (pred? (car kv) (cdr kv))
|
||||||
|
(cons kv res)
|
||||||
|
res)))))))
|
||||||
|
(cddr kvv))))
|
||||||
|
|
||||||
|
(define/doc (bst-balance bst)
|
||||||
|
("Unconditionally balances the BST.")
|
||||||
|
(kvv->bst
|
||||||
|
(bst->kvv bst)))
|
||||||
|
|
||||||
;; Module self-tests
|
;; Module self-tests
|
||||||
(define (util-bst-tests!)
|
(define (util-bst-tests!)
|
||||||
(run-tests
|
(run-tests
|
||||||
|
@ -241,12 +323,25 @@
|
||||||
(bst-count
|
(bst-count
|
||||||
(make-bst 'fixnum eq? <))
|
(make-bst 'fixnum eq? <))
|
||||||
0)
|
0)
|
||||||
(test-equal? bst-count
|
(test-equal? bst-set
|
||||||
(bst-count
|
(bst-count
|
||||||
(bst-set
|
(bst-set
|
||||||
(make-bst 'fixnum eq? <)
|
(make-bst 'fixnum eq? <)
|
||||||
1 2))
|
1 2))
|
||||||
1)
|
1)
|
||||||
|
(test-true bst-remove
|
||||||
|
(bst-empty?
|
||||||
|
(bst-remove
|
||||||
|
(bst-set
|
||||||
|
(make-bst 'fixnum eq? <)
|
||||||
|
1 2) 1)))
|
||||||
|
(test-equal? bst-balance
|
||||||
|
(bst-count
|
||||||
|
(bst-balance
|
||||||
|
(bst-set
|
||||||
|
(make-bst 'fixnum eq? <)
|
||||||
|
1 2)))
|
||||||
|
1)
|
||||||
))
|
))
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue