cartesian_tree/tree/
traits.rs1pub trait HasParent {
3 type Node: Clone;
4
5 fn parent(&self) -> Option<Self::Node>;
7}
8
9pub trait NodeEquality {
11 fn is_same(&self, other: &Self) -> bool;
13}
14
15pub trait HasChildren {
17 type Node: Clone;
18
19 fn children(&self) -> Vec<Self::Node>;
21}
22
23pub trait Walking: HasParent<Node = Self> + NodeEquality + Clone {
25 fn depth(&self) -> usize {
31 let mut depth = 0;
32 let mut current = self.clone();
33 while let Some(parent) = current.parent() {
34 depth += 1;
35 current = parent;
36 }
37 depth
38 }
39
40 fn walk_up(&self, steps: usize) -> Option<Self> {
50 let mut current = self.clone();
51 for _ in 0..steps {
52 current = current.parent()?;
53 }
54 Some(current)
55 }
56
57 fn root(&self) -> Self {
63 self.walk_up(self.depth()).unwrap_or_else(|| self.clone())
64 }
65
66 fn lca_with(&self, other: &Self) -> Option<Self> {
76 let mut own = self.clone();
77 let mut other = other.clone();
78
79 let own_depth = self.depth();
80 let other_depth = other.depth();
81
82 if own_depth > other_depth {
84 own = own.walk_up(own_depth - other_depth)?;
85 } else if other_depth > own_depth {
86 other = other.walk_up(other_depth - own_depth)?;
87 }
88
89 while !own.is_same(&other) {
91 own = own.parent()?;
92 other = other.parent()?;
93 }
94 Some(own)
95 }
96}
97
98impl<T> Walking for T where T: HasParent<Node = T> + NodeEquality + Clone {}
99
100#[cfg(test)]
101mod tests {
102 use super::*;
103 use crate::frame::Frame;
104 use nalgebra::{UnitQuaternion, Vector3};
105
106 #[test]
107 fn test_depth() {
108 let root = Frame::new_origin("root");
109 assert_eq!(root.depth(), 0);
110
111 let child = root
112 .add_child("child", Vector3::zeros(), UnitQuaternion::identity())
113 .unwrap();
114 assert_eq!(child.depth(), 1);
115
116 let grandchild = child
117 .add_child("grandchild", Vector3::zeros(), UnitQuaternion::identity())
118 .unwrap();
119 assert_eq!(grandchild.depth(), 2);
120 }
121
122 #[test]
123 fn test_walk_up() {
124 let root = Frame::new_origin("root");
125 let child = root
126 .add_child("child", Vector3::zeros(), UnitQuaternion::identity())
127 .unwrap();
128 let grandchild = child
129 .add_child("grandchild", Vector3::zeros(), UnitQuaternion::identity())
130 .unwrap();
131
132 assert!(grandchild.walk_up(0).unwrap().is_same(&grandchild));
133 assert!(grandchild.walk_up(1).unwrap().is_same(&child));
134 assert!(grandchild.walk_up(2).unwrap().is_same(&root));
135 assert!(grandchild.walk_up(3).is_none());
136 }
137
138 #[test]
139 fn test_root() {
140 let root = Frame::new_origin("root");
141 let child = root
142 .add_child("child", Vector3::zeros(), UnitQuaternion::identity())
143 .unwrap();
144 let grandchild = child
145 .add_child("grandchild", Vector3::zeros(), UnitQuaternion::identity())
146 .unwrap();
147
148 assert!(root.root().is_same(&root));
149 assert!(child.root().is_same(&root));
150 assert!(grandchild.root().is_same(&root));
151 }
152
153 #[test]
154 fn test_lca_with() {
155 let root = Frame::new_origin("root");
156 let child1 = root
157 .add_child("child1", Vector3::zeros(), UnitQuaternion::identity())
158 .unwrap();
159 let child2 = root
160 .add_child("child2", Vector3::zeros(), UnitQuaternion::identity())
161 .unwrap();
162 let grandchild1 = child1
163 .add_child("grandchild1", Vector3::zeros(), UnitQuaternion::identity())
164 .unwrap();
165 let grandchild2 = child2
166 .add_child("grandchild2", Vector3::zeros(), UnitQuaternion::identity())
167 .unwrap();
168
169 assert!(child1.lca_with(&child1).unwrap().is_same(&child1));
171 assert!(child1.lca_with(&child2).unwrap().is_same(&root));
173 assert!(grandchild1.lca_with(&child1).unwrap().is_same(&child1));
175 assert!(grandchild1.lca_with(&grandchild2).unwrap().is_same(&root));
177 }
178}