-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathbst.lsp
141 lines (119 loc) · 3.23 KB
/
bst.lsp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
;;;; SPDX-License-Identifier: 0BSD
;;;;
;;;; Binary Search Tree Data Structure
;;;; BST = nil | (key val BST BST)
;;;;
;;;;
;;;; VeLisp functions missing in AutoCAD
;;;;
(if (not take)
(defun take (n lst / acc)
;; Returns the first n elements in a list
(while (and (not (null lst)) (> n 0))
(setq acc (cons (car lst) acc)
lst (cdr lst)
n (1- n)))
(reverse acc)))
(if (not drop)
(defun drop (n lst)
;; Returns a sublist with the first n elements dropped
(while (and (not (null lst)) (> n 0))
(setq lst (cdr lst)
n (1- n)))
lst))
(if (not sublist)
(defun sublist (start len lst)
;; Returns a sublist of a list
(take len (drop start lst))))
;;;;
;;;; API
;;;;
;;; () -> BST
(defun bst_new ()
nil)
;;; (BST) -> T | nil
(defun bst_is_empty (bst)
(null bst))
;;; Build BST from sorted by key list:
;;; (((k . v) | (k v ...))) -> BST
(defun bst_from_list (lst / len mid c l r)
(if (null lst)
(bst_new)
(progn
(setq len (length lst)
mid (/ len 2)
c (nth mid lst)
l (sublist 0 mid lst)
r (sublist (1+ mid) len lst))
(bst_make_node (car c)
(cdr c)
(bst_from_list l)
(bst_from_list r)))))
;;; (BST) -> ((k . v) | (k v ...))
(defun bst_to_list (bst / k v l r)
(if (bst_is_empty bst)
nil
(progn
(setq k (bst_node_key bst)
v (bst_node_value bst)
l (bst_node_left bst)
r (bst_node_right bst))
(append (bst_to_list l)
(list (cons k v))
(bst_to_list r)))))
;;; (key BST) -> val | nil
(defun bst_get (key bst / k)
(if (bst_is_empty bst)
nil
(progn
(setq k (bst_node_key bst))
(cond ((< key k) (bst_get key (bst_node_left bst)))
((> key k) (bst_get key (bst_node_right bst)))
(T (bst_node_value bst))))))
;;; (key val BST) -> BST'
(defun bst_set (key val bst / k v l r)
(if (bst_is_empty bst)
(bst_make_node key val nil nil)
(progn
(setq k (bst_node_key bst)
v (bst_node_value bst)
l (bst_node_left bst)
r (bst_node_right bst))
(cond ((< key k) (bst_make_node k v (bst_set key val l) r))
((> key k) (bst_make_node k v l (bst_set key val r)))
(T (bst_make_node key val l r))))))
;;; (fun BST) -> BST'
;;; fun :: (key val) -> val'
(defun bst_map (fun bst / k v l r)
(if (bst_is_empty bst)
bst
(progn
(setq k (bst_node_key bst)
v (bst_node_value bst)
l (bst_node_left bst)
r (bst_node_right bst))
(bst_make_node k
(fun k v)
(bst_map fun l)
(bst_map fun r)))))
;;; TODO bst_fold
;;;;
;;;; Internal
;;;;
(defun bst_make_node (key val left right)
(list key val left right))
(defun bst_node_key (bst)
(car bst))
(defun bst_node_value (bst)
(cadr bst))
(defun bst_node_left (bst)
(caddr bst))
(defun bst_node_right (bst)
(cadddr bst))
;;;;
;;;; Tests
;;;;
;(setq bst (bst_new))
;(setq bst (bst_set 1 'one bst))
;(setq bst (bst_set 0 'zero bst))
;(setq bst (bst_set 2 'two bst))