1
2pub mod signed;
3
4use std::cmp;
5
6const RADIX: usize = 4;
8
9#[derive(Debug, Clone)]
10pub struct Node {
11 idx: u32,
12 parent: Option<u32>,
13 children: [Option<u32>; RADIX],
14 leaves: (u32, u32),
16 nb_tree_leaves: u32,
17 level: u32,
18}
19
20impl Node {
21 fn new_leaf(idx: usize, nb_tree_leaves: usize) -> Node {
22 let idx = idx as u32;
23 Node {
24 idx,
25 parent: None,
26 children: [None; RADIX],
27 leaves: (idx, (idx+1) % nb_tree_leaves as u32),
28 nb_tree_leaves: nb_tree_leaves as u32,
29 level: 0,
30 }
31 }
32
33 pub fn idx(&self) -> usize {
34 self.idx as usize
35 }
36
37 pub fn parent(&self) -> Option<usize> {
38 self.parent.map(|p| p as usize)
39 }
40
41 pub fn children(&self) -> impl Iterator<Item = usize> {
42 self.children.clone().into_iter().filter_map(|c| c).map(|c| c as usize)
43 }
44
45 pub fn level(&self) -> usize {
46 self.level as usize
47 }
48
49 pub fn leaves(&self) -> impl Iterator<Item = usize> + Clone {
51 let (first, last) = self.leaves;
52 let nb = self.nb_tree_leaves;
53 (first..)
54 .take(nb as usize)
55 .map(move |e| e % nb)
56 .take_while(move |e| first == last || *e != last)
57 .map(|e| e as usize)
58 }
59
60 pub fn is_leaf(&self) -> bool {
61 self.children.iter().all(|o| o.is_none())
62 }
63
64 pub fn is_root(&self) -> bool {
65 self.parent.is_none()
66 }
67}
68
69#[derive(Debug, Clone)]
73pub struct Tree {
74 nodes: Vec<Node>,
77 nb_leaves: usize,
78}
79
80impl Tree {
81 pub fn nb_nodes_for_leaves(nb_leaves: usize) -> usize {
84 let mut ret = nb_leaves;
85 let mut left = nb_leaves;
86 while left > 1 {
87 let radix = cmp::min(left, RADIX);
88 left -= radix;
89 left += 1;
90 ret += 1;
91 }
92 ret
93 }
94
95 pub fn new(
96 nb_leaves: usize,
97 ) -> Tree {
98 assert_ne!(nb_leaves, 0, "trees can't be empty");
99
100 let mut nodes = Vec::with_capacity(Tree::nb_nodes_for_leaves(nb_leaves));
101
102 nodes.extend((0..nb_leaves).map(|i| Node::new_leaf(i, nb_leaves)));
104
105 let mut cursor = 0;
106 while cursor < nodes.len() - 1 {
109 let mut children = [None; RADIX];
110 let mut nb_children = 0;
111 let mut max_child_level = 0;
112 while cursor < nodes.len() && nb_children < RADIX {
113 children[nb_children] = Some(cursor as u32);
114
115 let new_idx = nodes.len(); let child = &mut nodes[cursor];
117 child.parent = Some(new_idx as u32);
118
119 if child.level > max_child_level {
121 max_child_level = child.level;
122 }
123
124 cursor += 1;
125 nb_children += 1;
126 }
127 nodes.push(Node {
128 idx: nodes.len() as u32,
129 leaves: (
130 nodes[children.first().unwrap().unwrap() as usize].leaves.0,
131 nodes[children.iter().filter_map(|c| *c).last().unwrap() as usize].leaves.1,
132 ),
133 children,
134 level: max_child_level + 1,
135 parent: None,
136 nb_tree_leaves: nb_leaves as u32,
137 });
138 }
139
140 Tree { nodes, nb_leaves }
141 }
142
143 pub fn nb_leaves(&self) -> usize {
144 self.nb_leaves
145 }
146
147 pub fn nb_nodes(&self) -> usize {
148 self.nodes.len()
149 }
150
151 pub fn root(&self) -> &Node {
152 self.nodes.last().expect("no empty trees")
153 }
154
155 pub fn iter(&self) -> std::slice::Iter<'_, Node> {
157 self.nodes.iter()
158 }
159
160 pub fn into_iter(self) -> std::vec::IntoIter<Node> {
162 self.nodes.into_iter()
163 }
164
165 pub fn iter_branch(&self, leaf_idx: usize) -> BranchIter<'_> {
168 assert!(leaf_idx < self.nodes.len());
169 BranchIter {
170 tree: &self,
171 cursor: Some(leaf_idx),
172 }
173 }
174
175 pub fn parent_idx_of(&self, idx: usize) -> Option<usize> {
176 self.nodes.get(idx).and_then(|n| n.parent.map(|c| c as usize))
177 }
178
179 pub fn parent_idx_of_with_sibling_idx(&self, idx: usize) -> Option<(usize, usize)> {
182 self.nodes.get(idx).and_then(|n| n.parent).map(|parent_idx| {
183 let child_idx = self.nodes[parent_idx as usize].children.iter()
184 .position(|c| *c == Some(idx as u32))
185 .expect("broken tree");
186 (self.nodes[parent_idx as usize].idx as usize, child_idx as usize)
187 })
188 }
189
190}
191
192pub struct BranchIter<'a> {
194 tree: &'a Tree,
195 cursor: Option<usize>,
196}
197
198impl<'a> Iterator for BranchIter<'a> {
199 type Item = &'a Node;
200 fn next(&mut self) -> Option<Self::Item> {
201 if let Some(cursor) = self.cursor {
202 let ret = &self.tree.nodes[cursor];
203 self.cursor = ret.parent();
204 Some(ret)
205 } else {
206 None
207 }
208 }
209}
210
211#[cfg(test)]
212mod test {
213 use std::collections::HashSet;
214
215use super::*;
216
217 #[test]
218 fn test_simple_tree() {
219 for n in 1..100 {
220 let tree = Tree::new(n);
221
222 assert!(tree.nodes.iter().rev().skip(1).all(|n| n.parent.is_some()));
223 assert!(tree.nodes.iter().enumerate().skip(tree.nb_leaves).all(|(i, n)| {
224 n.children.iter().filter_map(|v| *v)
225 .all(|c| tree.nodes[c as usize].parent == Some(i as u32))
226 }));
227 assert!(tree.nodes.iter().enumerate().rev().skip(1).all(|(i, n)| {
228 tree.nodes[n.parent.unwrap() as usize].children.iter().find(|c| **c == Some(i as u32)).is_some()
229 }));
230 assert_eq!(Tree::nb_nodes_for_leaves(n), tree.nb_nodes(), "leaves: {}", n);
231 }
232 }
233
234 #[test]
235 fn test_leaves_range() {
236 for n in 1..42 {
237 let tree = Tree::new(n);
238
239 for node in &tree.nodes[0..tree.nb_leaves()] {
240 assert_eq!(node.leaves().collect::<Vec<_>>(), vec![node.idx()]);
241 }
242 for node in tree.iter() {
243 if !node.is_leaf() {
244 assert_eq!(
245 node.leaves().count(),
246 node.children().map(|c| tree.nodes[c].leaves().count()).sum::<usize>(),
247 "idx: {}", node.idx(),
248 );
249 }
250 assert!(node.leaves().all(|l| l < tree.nb_leaves()));
251 assert_eq!(
252 node.leaves().count(),
253 node.leaves().collect::<HashSet<_>>().len(),
254 );
255 }
256 println!("n={n} ok");
257 }
258 }
259}