use crate::branch::Branch;
use std::cmp::Ordering;
use std::collections::VecDeque;
use std::mem;
#[derive(Debug, Clone, PartialOrd, PartialEq)]
pub(crate) enum Node<T>
where T: Copy + Clone + Ord + Eq
{
Empty,
NonEmpty(Box<Branch<T>>),
}
impl<T> Default for Node<T>
where T: Copy + Clone + Ord + Eq
{
#[inline]
fn default() -> Self {
Node::Empty
}
}
#[allow(dead_code)]
impl<T> Node<T>
where T: Copy + Clone + Ord + Eq
{
#[inline]
pub(crate) fn new() -> Self {
Node::default()
}
#[inline]
pub(crate) fn ignore(&self) -> &Box<Branch<T>> {
if let Node::NonEmpty(ref branch) = *self {
return branch;
} else {
panic!("Empty tree");
}
}
#[inline]
pub(crate) fn ignore_mut(&mut self) -> &mut Box<Branch<T>> {
if let Node::NonEmpty(ref mut branch) = *self {
return branch;
} else {
panic!("Empty tree");
}
}
#[inline]
pub(crate) fn get_key(&self) -> &T {
&self.ignore().key
}
pub(crate) fn insert(&mut self, val: &T) {
match *self {
Node::Empty => {
*self = Node::NonEmpty(Box::new(Branch {
key: (*val).clone(),
right: Node::Empty,
left: Node::Empty,
}))
}
Node::NonEmpty(ref mut branch) => {
if branch.key <= *val {
branch.right.insert(val);
} else {
branch.left.insert(val);
}
}
}
}
pub(crate) fn find(&self, val: &T) -> &Self {
let mut find = self;
while let Node::NonEmpty(ref branch) = *find {
match val.cmp(find.get_key()) {
Ordering::Less => find = &branch.left,
Ordering::Greater => find = &branch.right,
Ordering::Equal => return find,
}
}
&Node::Empty
}
pub(crate) fn min(&self) -> &Self {
let mut min = self;
while min.ignore().left != Node::Empty {
min = &min.ignore().left;
}
min
}
pub(crate) fn max(&self) -> &Self {
let mut max = self;
while max.ignore().right != Node::Empty {
max = &max.ignore().right;
}
max
}
pub(crate) fn walk(&self) -> VecDeque<T> {
return match *self {
Node::Empty => VecDeque::new(),
Node::NonEmpty(ref branch) => {
let mut result = branch.left.walk();
result.push_back(branch.key.clone());
result.extend(branch.right.walk());
result
}
}
}
pub(crate) fn rec_drop(&mut self) {
match *self {
Node::Empty => return,
Node::NonEmpty(ref mut branch) => {
branch.left.rec_drop();
branch.right.rec_drop();
mem::drop(branch.key);
*self = Node::Empty;
}
}
}
pub(crate) fn remove(&mut self, val: &T) -> (bool, Vec<T>) {
let mut find = self;
let mut search = false;
while *find != Node::Empty {
match val.cmp(find.get_key()) {
Ordering::Less => find = &mut find.ignore_mut().left,
Ordering::Greater => find = &mut find.ignore_mut().right,
Ordering::Equal => {
search = true;
break;
},
}
}
let mut safe = Vec::new();
if search {
safe.extend(find.ignore().left.walk());
safe.extend(find.ignore().right.walk());
find.rec_drop();
} else {
if let Node::NonEmpty(ref node) = *find {
if node.key == *val {
search = true;
safe.extend(node.left.walk());
safe.extend(node.right.walk());
find.rec_drop();
}
}
}
(search, safe)
}
}