use std::ops::{Deref, DerefMut};
use std::ptr;
use std::cmp::max;
use std::fmt;
pub type Link<T> = Option<Box<Node<T>>>;
pub struct Node<T: Clone> {
elem: T,
parent: *mut Node<T>,
left_child: Link<T>,
right_child: Link<T>,
}
impl<T: Clone> Node<T> {
pub fn new(elem: T) -> Box<Self> {
Box::new(Node {
elem,
parent: ptr::null_mut(),
left_child: None,
right_child: None,
})
}
pub fn get(&self) -> &T {
&self.elem
}
pub fn get_mut(&mut self) -> &mut T {
&mut self.elem
}
pub fn is(&self, node: &Node<T>) -> bool {
self as *const Node<T> == node as *const Node<T>
}
pub fn check_left_child(&self, node: &Node<T>) -> bool {
match self.left_child_opt() {
Some(child) => child.is(node),
None => false,
}
}
pub fn check_right_child(&self, node: &Node<T>) -> bool {
match self.right_child_opt() {
Some(child) => child.is(node),
None => false,
}
}
pub fn is_left_child(&self) -> Option<bool> {
match self.parent_opt() {
Some(parent) => Some(parent.check_left_child(self)),
None => None,
}
}
pub fn is_leaf(&self) -> bool {
!self.has_left_child() && !self.has_right_child()
}
pub fn has_left_child(&self) -> bool {
self.left_child.is_some()
}
pub fn has_right_child(&self) -> bool {
self.right_child.is_some()
}
pub fn has_parent(&self) -> bool {
!self.parent.is_null()
}
pub fn set_left_child(&mut self, child: Link<T>) {
self.take_left_child(); if let Some(mut child) = child {
child.set_parent(self);
self.left_child = Some(child);
}
}
pub fn set_right_child(&mut self, child: Link<T>) {
self.take_right_child(); if let Some(mut child) = child {
child.set_parent(self);
self.right_child = Some(child);
}
}
pub fn set_parent(&mut self, parent: *mut Node<T>) {
self.remove_from_parent();
self.parent = parent;
}
pub(crate) fn left_child_mut_ptr_opt(&mut self) -> Option<*mut Node<T>> {
self.left_child.as_mut().map(|n| (&mut **n) as *mut Node<T>)
}
pub(crate) fn right_child_mut_ptr_opt(&mut self) -> Option<*mut Node<T>> {
self.right_child.as_mut().map(|n| (&mut **n) as *mut Node<T>)
}
pub fn left_child_mut_opt(&mut self) -> Option<&mut Node<T>> {
self.left_child.as_mut().map(|n| &mut **n)
}
pub fn right_child_mut_opt(&mut self) -> Option<&mut Node<T>> {
self.right_child.as_mut().map(|n| &mut **n)
}
pub fn parent_mut_opt(&mut self) -> Option<&mut Node<T>> {
if self.has_parent() {
Some(unsafe { &mut *self.parent })
} else {
None
}
}
pub fn left_child_opt(&self) -> Option<&Node<T>> {
self.left_child.as_ref().map(|n| &**n)
}
pub fn right_child_opt(&self) -> Option<&Node<T>> {
self.right_child.as_ref().map(|n| &**n)
}
pub fn parent_opt(&self) -> Option<&Node<T>> {
if self.has_parent() {
Some(unsafe { &*self.parent })
} else {
None
}
}
pub fn take_left_child(&mut self) -> Link<T> {
if let Some(mut child) = self.left_child.take() {
child.parent = ptr::null_mut();
Some(child)
} else {
None
}
}
pub fn take_right_child(&mut self) -> Link<T> {
if let Some(mut child) = self.right_child.take() {
child.parent = ptr::null_mut();
Some(child)
} else {
None
}
}
fn remove_child(&mut self, child: &Node<T>) {
let mut removed = false;
if Some(child) == self.left_child_opt() {
removed = true;
self.left_child = None;
}
if Some(child) == self.right_child_opt() {
assert!(!removed, "Node set as both left child and right child.");
removed = true;
self.right_child = None;
}
assert!(removed, "Node isn't a child of this node.");
}
pub fn remove_from_parent(&mut self) {
if self.has_parent() {
let parent = unsafe { &mut *self.parent };
self.parent = ptr::null_mut();
parent.remove_child(self);
}
}
#[inline]
pub fn height(&self) -> i32 {
1 + max(
self.left_child_opt().map_or(0, |node| node.height()),
self.right_child_opt().map_or(0, |node| node.height())
)
}
#[inline]
pub fn depth(&self) -> i32 {
match self.parent_opt() {
Some(parent) => 1 + parent.depth(),
None => 0
}
}
#[inline]
pub fn size(&self) -> i32 {
let mut result = 1;
if !self.is_leaf() {
if let Some(left_child) = self.left_child_opt() {
result += left_child.size();
}
if let Some(right_child) = self.right_child_opt() {
result += right_child.size();
}
}
result
}
#[inline]
pub fn copy(&self) -> Box<Node<T>> {
Box::new(Node {
elem: self.elem.clone(),
parent: ptr::null_mut(),
left_child: None,
right_child: None,
})
}
#[inline]
pub fn deepcopy(&self) -> Box<Node<T>> {
let mut temp_copy = self.copy();
if let Some(child) = self.left_child_opt() {
let child = child.deepcopy();
temp_copy.set_left_child(Some(child));
}
if let Some(child) = self.right_child_opt() {
let child = child.deepcopy();
temp_copy.set_right_child(Some(child));
}
temp_copy
}
pub fn insert_random(&mut self, node: Box<Node<T>>) {
match rand::random() {
true => {
if let Some(child) = self.left_child_mut_opt() {
child.insert_random(node);
} else {
self.set_left_child(Some(node));
return
}
},
false => {
if let Some(child) = self.right_child_mut_opt() {
child.insert_random(node);
} else {
self.set_right_child(Some(node));
return
}
}
}
}
pub fn display(&self, level: i32) {
if let Some(child) = self.left_child_opt() {
child.display(level + 1);
}
let tabs: String = (0..level)
.map(|_| "\t")
.collect::<Vec<_>>()
.join("");
println!("{}{:?}\n", tabs, self);
if let Some(child) = self.right_child_opt() {
child.display(level + 1);
}
}
}
impl<T: Clone> Deref for Node<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.elem
}
}
impl<T: Clone> DerefMut for Node<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.elem
}
}
impl<T: Clone> PartialEq for Node<T> {
fn eq(&self, other: &Self) -> bool {
self as *const Node<T> == other as *const Node<T>
}
}
impl<T: Clone> fmt::Debug for Node<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Node[{:p}]={{parent = {:?}, left = {:?}, right = {:?}}}",
self, self.parent, self.left_child, self.right_child)
}
}