git.fiddlerwoaroof.com
Browse code

feat: binary tree utilities

Ed Langley authored on 05/09/2020 00:15:50
Showing 1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,70 @@
1
+(defpackage :fwoar.binary-tree
2
+  (:use :cl )
3
+  (:export ))
4
+(in-package :fwoar.binary-tree)
5
+
6
+(fw.lu:defclass+ bt ()
7
+  ((left :initarg :left :accessor left)
8
+   (value :initarg :value :accessor value)
9
+   (right :initarg :right :accessor right)))
10
+(defmethod print-object ((o bt) s)
11
+  (format s "[~s < ~s > ~s]"
12
+          (left o)
13
+          (value o)
14
+          (right o)))
15
+
16
+(defgeneric visit (client tree))
17
+(defun visit-in-order (client tree)
18
+  (let ((left (left tree))
19
+        (right (right tree)))
20
+    (when left
21
+      (visit-in-order client (left tree)))
22
+    (visit client tree)
23
+    (when right
24
+      (visit-in-order client (right tree))))
25
+  tree)
26
+
27
+(fw.lu:defclass+ counter ()
28
+  ((value :initform 0 :accessor value)))
29
+(defmethod visit ((client counter) tree)
30
+  (setf (value tree)
31
+        (value client))
32
+  (incf (value client)))
33
+
34
+(fw.lu:defclass+ stragglers ()
35
+  ((elts :initarg :elts :accessor elts)))
36
+(defmethod visit ((client stragglers) tree)
37
+  (declare (optimize (debug 3)))
38
+  (fw.lu:with-accessors* (elts) client
39
+    (when (and elts (null (left tree)))
40
+      (let ((n-l (pop elts))
41
+            (n-r (pop elts)))
42
+        (setf (left tree) (bt nil n-l nil))
43
+        (when n-r
44
+          (setf (right tree) (bt nil n-r nil)))))))
45
+
46
+(defmethod visit ((client (eql :print)) tree)
47
+  (fresh-line)
48
+  (prin1 (value tree))
49
+  (princ #\tab)
50
+  (prin1 tree)
51
+  (terpri))
52
+
53
+(defun dense-tree (levels cur)
54
+  (if (null cur)
55
+      (let ((layer (loop repeat (expt 2 (1- levels)) collect (bt nil nil nil))))
56
+        (dense-tree (1- levels)
57
+                    layer))
58
+      (if (> levels 0)
59
+          (dense-tree (1- levels)
60
+                      (loop for (l r) on cur by #'cddr
61
+                            collect (bt l nil r)))
62
+          (car cur))))
63
+
64
+(defun complete-bt-of-size (n)
65
+  (let* ((l2_n (log n 2))
66
+         (height (ceiling l2_n))
67
+         (max-node-count (1- (expt 2 height)))
68
+         (full-bt-size (1- (expt 2 (1- height))))
69
+         (leftovers (- n full-bt-size)))
70
+    (values height max-node-count full-bt-size leftovers)))