Skip to content

Instantly share code, notes, and snippets.

@akr4
Last active September 22, 2019 23:10
Show Gist options
  • Save akr4/a01934f80484fd7f1a84d0dbe6944d95 to your computer and use it in GitHub Desktop.
Save akr4/a01934f80484fd7f1a84d0dbe6944d95 to your computer and use it in GitHub Desktop.
tree! macro which generates tree on leetcode
use std::cell::RefCell;
#[cfg(test)]
use std::collections::LinkedList;
use std::rc::Rc;
#[derive(Debug, PartialEq, Eq)]
pub struct TreeNode {
pub val: i32,
pub left: Option<Rc<RefCell<TreeNode>>>,
pub right: Option<Rc<RefCell<TreeNode>>>,
}
impl TreeNode {
#[inline]
pub fn new(val: i32) -> Self {
TreeNode {
val,
left: None,
right: None,
}
}
}
#[cfg(test)]
pub fn make_tree(values: &[Option<i32>]) -> Option<Rc<RefCell<TreeNode>>> {
if values.is_empty() {
return None;
}
let mut queue: LinkedList<Rc<RefCell<TreeNode>>> = LinkedList::new();
let mut values = values.into_iter();
let first = values.next().unwrap();
if first.is_none() {
return None;
}
let root = Rc::new(RefCell::new(TreeNode::new(first.unwrap())));
queue.push_back(root.clone());
while let Some(node) = queue.pop_front() {
if let Some(value) = values.next() {
if let Some(x) = value {
let new_node = Rc::new(RefCell::new(TreeNode::new(*x)));
queue.push_back(new_node.clone());
node.borrow_mut().left = Some(new_node);
}
}
if let Some(value) = values.next() {
if let Some(x) = value {
let new_node = Rc::new(RefCell::new(TreeNode::new(*x)));
queue.push_back(new_node.clone());
node.borrow_mut().right = Some(new_node);
}
}
}
Some(root)
}
#[cfg(test)]
macro_rules! tree {
($($x:tt),*) => {
crate::tree::make_tree(&[$(tree_node!($x)),*]);
};
($($x:tt),*,) => {
crate::tree::make_tree(&[$(tree_node!($x)),*]);
};
}
#[cfg(test)]
macro_rules! tree_node {
(null) => {
None
};
($x:expr) => {
Some($x)
};
}
#[test]
fn test_make_tree() {
assert_eq!(
*make_tree(&[Some(2), Some(1), Some(3)]).unwrap().borrow(),
TreeNode {
val: 2,
left: Some(Rc::new(RefCell::new(TreeNode {
val: 1,
left: None,
right: None,
}))),
right: Some(Rc::new(RefCell::new(TreeNode {
val: 3,
left: None,
right: None,
}))),
}
);
assert_eq!(
*make_tree(&[Some(5), Some(1), Some(4), None, None, Some(3), Some(6)])
.unwrap()
.borrow(),
TreeNode {
val: 5,
left: Some(Rc::new(RefCell::new(TreeNode {
val: 1,
left: None,
right: None,
}))),
right: Some(Rc::new(RefCell::new(TreeNode {
val: 4,
left: Some(Rc::new(RefCell::new(TreeNode {
val: 3,
left: None,
right: None,
}))),
right: Some(Rc::new(RefCell::new(TreeNode {
val: 6,
left: None,
right: None,
}))),
}))),
}
);
assert_eq!(
*make_tree(&[
Some(1),
Some(2),
None,
Some(3),
None,
Some(4),
None,
Some(5)
])
.unwrap()
.borrow(),
TreeNode {
val: 1,
left: Some(Rc::new(RefCell::new(TreeNode {
val: 2,
left: Some(Rc::new(RefCell::new(TreeNode {
val: 3,
left: Some(Rc::new(RefCell::new(TreeNode {
val: 4,
left: Some(Rc::new(RefCell::new(TreeNode {
val: 5,
left: None,
right: None,
}))),
right: None,
}))),
right: None,
}))),
right: None,
}))),
right: None,
}
)
}
#[test]
fn test_tree_macro() {
assert_eq!(
tree![10, 5, 15, null, null, 6, 20],
make_tree(&[Some(10), Some(5), Some(15), None, None, Some(6), Some(20)])
);
assert_eq!(tree![1], make_tree(&[Some(1)]));
assert_eq!(tree![null], make_tree(&[None]));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment