use alloc::boxed::Box;
use core::mem;
mod insert;
mod remove;
mod traverse;
pub use traverse::*;
#[derive(Clone, Debug, PartialEq)]
pub struct AANode<T>(Option<Box<Node<T>>>);
#[derive(Clone, Debug, PartialEq)]
pub(super) struct Node<T> {
pub(super) level: u8,
pub(super) content: T,
pub(super) left_child: AANode<T>,
pub(super) right_child: AANode<T>
}
impl<T> From<Node<T>> for AANode<T> {
fn from(node: Node<T>) -> Self {
Self(Some(Box::new(node)))
}
}
impl<T> Default for AANode<T> {
fn default() -> Self {
Self::new()
}
}
impl<T> From<T> for AANode<T> {
fn from(content: T) -> Self {
Node {
level: 1,
content,
left_child: Self(None),
right_child: Self(None)
}
.into()
}
}
impl<T> AANode<T> {
pub(super) fn unbox(self) -> Option<Node<T>> {
self.0.map(|this| *this)
}
pub(super) fn as_ref(&self) -> Option<&Node<T>> {
self.0.as_ref().map(Box::as_ref)
}
fn as_mut(&mut self) -> Option<&mut Node<T>> {
self.0.as_mut().map(Box::as_mut)
}
fn take(&mut self) -> Self {
Self(self.0.take())
}
pub const fn new() -> Self {
Self(None)
}
pub const fn is_nil(&self) -> bool {
self.0.is_none()
}
pub fn is_leaf(&self) -> bool {
match self.as_ref() {
None => false,
Some(Node {
left_child,
right_child,
..
}) => left_child.is_nil() && right_child.is_nil()
}
}
pub fn has_left_child(&self) -> bool {
match self.as_ref() {
None => false,
Some(Node { left_child, .. }) => !left_child.is_nil()
}
}
pub fn has_right_child(&self) -> bool {
match self.as_ref() {
None => false,
Some(Node { right_child, .. }) => !right_child.is_nil()
}
}
fn left_child_mut(&mut self) -> Option<&mut Self> {
self.as_mut().and_then(|Node { left_child, .. }| {
(!left_child.is_nil()).then(|| left_child)
})
}
fn right_child_mut(&mut self) -> Option<&mut Self> {
self.as_mut().and_then(|Node { right_child, .. }| {
(!right_child.is_nil()).then(|| right_child)
})
}
fn set_right_child(&mut self, child: Self) {
match self.as_mut() {
None => panic!("I don't have a right child"),
Some(Node { right_child, .. }) => {
*right_child = child;
}
}
}
pub(super) fn level(&self) -> u8 {
match self.as_ref() {
None => 0,
Some(Node { level, .. }) => *level
}
}
fn content_mut(&mut self) -> Option<&mut T> {
self.as_mut().map(|Node { content, .. }| content)
}
fn set_level(&mut self, level: u8) {
match self.as_mut() {
None => panic!("Cannot change level of Nil"),
Some(Node { level: l, .. }) => mem::replace(l, level)
};
}
fn skew(mut self) -> Self {
match self.as_mut() {
None => self,
Some(Node {
level,
left_child: l,
..
}) => {
let b_node = match l.as_mut() {
Some(Node {
level: l_level,
right_child: b,
..
}) if level == l_level => b.take(),
_ => return self
};
let mut l_node = mem::replace(l, b_node);
l_node
.as_mut()
.unwrap_or_else(|| unreachable!())
.right_child = self;
l_node
}
}
}
fn split(mut self) -> Self {
match self.as_mut() {
None => self,
Some(Node {
level,
right_child: r,
..
}) => {
let b_node = match r.as_mut() {
Some(Node {
left_child: b,
right_child: x,
..
}) if &x.level() == level => b.take(),
_ => return self
};
let mut r_node = mem::replace(r, b_node);
let r_node_mut = r_node.as_mut().unwrap_or_else(|| unreachable!());
r_node_mut.level += 1;
r_node_mut.left_child = self;
r_node
}
}
}
}
#[cfg(all(test, not(feature = "benchmark")))]
mod test {
use super::*;
macro_rules! tree {
() => {
AANode::new()
};
(Nil) => {
AANode::new()
};
($content:expr) => {
AANode::from($content)
};
($content:expr => [$level:expr, $left:tt, $right:tt]) => {
{
let _left = tree!(@internal $left);
let _right = tree!(@internal $right);
AANode(Some(Box::new(Node {
level: $level,
content: $content,
left_child: _left,
right_child: _right
})))
}
};
(@internal ($content:expr => [$level:expr, $left:tt, $right:tt])) => {
tree!($content => [$level, $left, $right])
};
(@internal $inner:tt) => {
tree!($inner)
};
}
#[test]
fn test_skew_nil() {
let root: AANode<char> = tree!();
println!("Input: {:?}", root);
let skewed = root.skew();
let expected = tree!();
assert_eq!(skewed, expected);
}
#[test]
fn test_skew_leaf() {
let root = tree!('T');
println!("Input: {:?}", root);
let skewed = root.skew();
let expected = tree!('T');
assert_eq!(skewed, expected);
}
#[test]
fn test_skew_simple() {
let root = tree!('T' => [2, ('L' => [2, Nil, Nil]), 'R']);
println!("Input: {:?}", root);
let skewed = root.skew();
let expected = tree!('L' => [2, Nil, ('T' => [2, Nil, 'R'])]);
assert_eq!(skewed, expected);
}
#[test]
fn test_skew_full() {
let root = tree!('T' => [2, ('L' => [2, 'A', 'B']), 'R']);
println!("Input: {:?}", root);
let skewed = root.skew();
let expected = tree!('L' => [2, 'A', ('T' => [2, 'B', 'R'])]);
assert_eq!(skewed, expected);
}
#[test]
fn test_split_nil() {
let root: AANode<char> = tree!();
println!("Input: {:?}", root);
let splitted = root.split();
let expected = tree!();
assert_eq!(splitted, expected);
}
#[test]
fn test_split_leaf() {
let root = tree!('T');
println!("Input: {:?}", root);
let splitted = root.split();
let expected = tree!('T');
assert_eq!(splitted, expected);
}
#[test]
fn test_split_good_tree() {
let root = tree!('T' => [2, 'A', ('R' => [2, 'B', 'X'])]);
println!("Input: {:?}", root);
let splitted = root.split();
let expected = tree!('T' => [2, 'A', ('R' => [2, 'B', 'X'])]);
assert_eq!(splitted, expected);
}
#[test]
fn test_split_bad_tree() {
let root = tree!('T' => [2, 'A', ('R' => [2, 'B', ('X' => [2, 'Y', 'Z'])])]);
println!("Input: {:?}", root);
let splitted = root.split();
let expected = tree!('R' => [3, ('T' => [2, 'A', 'B']), ('X' => [2, 'Y', 'Z'])]);
assert_eq!(splitted, expected);
}
#[test]
fn test_insert_greater() {
let mut root = tree!();
for content in ['A', 'B', 'C', 'D', 'E', 'F', 'G'].iter() {
assert!(root.insert(*content));
}
let expected = tree!('D' => [3, ('B' => [2, 'A', 'C']), ('F' => [2, 'E', 'G'])]);
assert_eq!(root, expected);
}
#[test]
fn test_insert_smaller() {
let mut root = tree!();
for content in ['Z', 'Y', 'X', 'W', 'V'].iter() {
assert!(root.insert(*content));
}
let expected = tree!('W' => [2, 'V', ('Y' => [2, 'X', 'Z'])]);
assert_eq!(root, expected);
}
#[test]
fn test_insert_multiple() {
let mut root = tree!();
for content in ['A', 'A'].iter() {
root.insert(*content);
}
let expected = tree!('A');
assert_eq!(root, expected);
}
#[test]
fn test_remove_successor() {
let mut root = tree!('B' => [1, Nil, 'C']);
println!("Input: `{:?}`", root);
let removed = root.remove(&'B');
let expected = tree!('C');
assert_eq!(removed, Some('B'));
assert_eq!(root, expected);
}
#[test]
fn test_remove_predecessor() {
let mut root = tree!('B' => [2, 'A', 'C']);
println!("Input: `{:?}`", root);
let removed = root.remove(&'B');
let expected = tree!('A' => [1, Nil, 'C']);
assert_eq!(removed, Some('B'));
assert_eq!(root, expected);
}
#[test]
fn test_remove_complex() {
let mut root = tree!(30 => [3, (15 => [2, 5, 20]), (70 => [3, (50 => [2, 35, (60 => [2, 55, 65])]), (85 => [2, 80, 90])])]);
println!("Input: `{:?}`", root);
let removed = root.remove(&5);
let expected = tree!(50 => [3, (30 => [2, (15 => [1, Nil, 20]), 35]), (70 => [3, (60 => [2, 55, 65]), (85 => [2, 80, 90])])]);
assert_eq!(removed, Some(5));
assert_eq!(root, expected);
}
}