addedd delete node and return
This commit is contained in:
parent
007ecbc980
commit
deb0c8d899
68
Cargo.lock
generated
68
Cargo.lock
generated
@ -2,6 +2,74 @@
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.155"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
||||
|
||||
[[package]]
|
||||
name = "play"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
276
src/main.rs
276
src/main.rs
@ -1,12 +1,18 @@
|
||||
use std::{borrow::BorrowMut, collections::HashMap};
|
||||
use core::borrow;
|
||||
use std::{
|
||||
cell::RefCell,
|
||||
collections::{HashMap, VecDeque},
|
||||
rc::Rc,
|
||||
};
|
||||
|
||||
use play::{
|
||||
linked_list::ListNode,
|
||||
list_dump::test_list1,
|
||||
node_struct::{self, TreeNode},
|
||||
tree_dump::{
|
||||
test10, test11, test2, test5, test6, test7, test8, test9, test_complete_six_nodes,
|
||||
test_simple_full_two_level, test_tree1, test_two_arms,
|
||||
full_tree_level, test10, test11, test12, test2, test5, test6, test7, test8, test9,
|
||||
test_big_random_wiggle, test_complete_six_nodes, test_simple_full_two_level, test_tree1,
|
||||
test_two_arms,
|
||||
},
|
||||
};
|
||||
|
||||
@ -17,226 +23,96 @@ fn main() {
|
||||
//add_node(root.clone(), (1, 2, 1)); // Add 2 as left child of 1
|
||||
//add_node(root.clone(), (1, 3, 0)); // Add 3 as right child of 1
|
||||
//add_node(root.clone(), (2, 4, 1)); // Add 4 as left child of 2
|
||||
println!("{:?}", root);
|
||||
// return;
|
||||
let tree = full_tree_level(2, 1);
|
||||
let root_val = tree.clone().unwrap().borrow().val;
|
||||
println!("start tree {:?}", tree);
|
||||
println!(
|
||||
"{:?}",
|
||||
create_binary_tree(vec![
|
||||
vec![85, 82, 1],
|
||||
vec![74, 85, 1],
|
||||
vec![39, 70, 0],
|
||||
vec![82, 38, 1],
|
||||
vec![74, 39, 0],
|
||||
vec![39, 13, 1]
|
||||
]) //maximum_gain("cdbcbbaaabab".to_string(), 4, 5) //count_nodes(foo) //is_cousins(test_tree1(), 2, 3) //search_bst(sorted_array_to_bst(vec![1, 2, 3, 4, 7]), 2)
|
||||
del_nodes(tree, vec![4, 5]) //get_directions(tree, root_val, last_val) //maximum_gain("cdbcbbaaabab".to_string(), 4, 5) //count_nodes(foo) //is_cousins(test_tree1(), 2, 3) //search_bst(sorted_array_to_bst(vec![1, 2, 3, 4, 7]), 2)
|
||||
);
|
||||
//;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
pub fn del_nodes(
|
||||
root: Option<Rc<RefCell<TreeNode>>>,
|
||||
mut to_delete: Vec<i32>,
|
||||
) -> Vec<Option<Rc<RefCell<TreeNode>>>> {
|
||||
let Some(root_node) = root else {
|
||||
return Vec::new();
|
||||
};
|
||||
let root_val = root_node.borrow().val;
|
||||
let mut root_of_forrest = if !to_delete.iter().any(|x| *x == root_val) {
|
||||
vec![Some(root_node.clone())]
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
let mut nodes_to_handle = VecDeque::new();
|
||||
nodes_to_handle.push_front(root_node);
|
||||
|
||||
pub fn create_binary_tree(descriptions: Vec<Vec<i32>>) -> Option<Rc<RefCell<TreeNode>>> {
|
||||
if descriptions.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut node_map: HashMap<i32, Rc<RefCell<TreeNode>>> = HashMap::new();
|
||||
let mut child_set = std::collections::HashSet::new();
|
||||
|
||||
for edge in &descriptions {
|
||||
let parent_val = edge[0];
|
||||
let child_val = edge[1];
|
||||
|
||||
node_map
|
||||
.entry(parent_val)
|
||||
.or_insert_with(|| Rc::new(RefCell::new(TreeNode::new(parent_val))));
|
||||
node_map
|
||||
.entry(child_val)
|
||||
.or_insert_with(|| Rc::new(RefCell::new(TreeNode::new(child_val))));
|
||||
}
|
||||
|
||||
for edge in descriptions {
|
||||
let parent_val = edge[0];
|
||||
let child_val = edge[1];
|
||||
let is_left = edge[2] == 1;
|
||||
|
||||
let parent_node = node_map.get(&parent_val).unwrap();
|
||||
let child_node = node_map.get(&child_val).unwrap();
|
||||
|
||||
if is_left {
|
||||
(**parent_node).borrow_mut().left = Some(child_node.clone());
|
||||
} else {
|
||||
(**parent_node).borrow_mut().right = Some(child_node.clone());
|
||||
}
|
||||
|
||||
child_set.insert(child_val);
|
||||
}
|
||||
let root_val = *node_map.keys().find(|&&k| !child_set.contains(&k)).unwrap();
|
||||
node_map.remove(&root_val)
|
||||
}
|
||||
|
||||
pub fn create_binary_tree_v2(descriptions: Vec<Vec<i32>>) -> Option<Rc<RefCell<TreeNode>>> {
|
||||
if descriptions.is_empty() {
|
||||
return None;
|
||||
}
|
||||
|
||||
let mut known_nodes: Vec<(Rc<RefCell<TreeNode>>, Vec<i32>)> = Vec::new();
|
||||
|
||||
for edge in descriptions {
|
||||
println!("Handling edge: {:?}", edge);
|
||||
println!("Known: {:?}", known_nodes);
|
||||
let parent_id = known_nodes
|
||||
while let Some(node) = nodes_to_handle.pop_back() {
|
||||
println!("Delete nodes {:?}", to_delete);
|
||||
let node_val = node.borrow().val;
|
||||
println!("node val {:?}", node_val);
|
||||
let delete_idx = to_delete
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|(_, (_, ids))| ids.contains(&edge[0]))
|
||||
.map(|(id, _)| id);
|
||||
.find(|(_, x)| **x == node_val)
|
||||
.map(|(i, _)| i);
|
||||
|
||||
let child_id = known_nodes
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|(_, (_, ids))| ids.contains(&edge[1]))
|
||||
.map(|(id, _)| id);
|
||||
println!("Ids are: {:?}", (parent_id, child_id));
|
||||
let (parent_tree, child_tree) = match (parent_id, child_id) {
|
||||
(None, None) => (None, None),
|
||||
(None, Some(id)) => (None, Some(known_nodes.remove(id))),
|
||||
(Some(id), None) => (Some(known_nodes.remove(id)), None),
|
||||
(Some(id_p), Some(id_c)) => {
|
||||
if id_p > id_c {
|
||||
let p = known_nodes.remove(id_p);
|
||||
(Some(p), Some(known_nodes.remove(id_c)))
|
||||
} else {
|
||||
let c = known_nodes.remove(id_c);
|
||||
(Some(known_nodes.remove(id_p)), Some(c))
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
match (parent_tree, child_tree) {
|
||||
(None, None) => {
|
||||
let known_node_vals = vec![edge[0], edge[1]];
|
||||
let child_node = Rc::new(RefCell::new(TreeNode::new(edge[1])));
|
||||
let mut root_node = TreeNode::new(edge[0]);
|
||||
if edge[2] == 1 {
|
||||
root_node.left = Some(child_node);
|
||||
} else {
|
||||
root_node.right = Some(child_node);
|
||||
}
|
||||
|
||||
known_nodes.push((Rc::new(RefCell::new(root_node)), known_node_vals));
|
||||
}
|
||||
(Some(par), None) => {
|
||||
let (tree, mut ids) = par;
|
||||
add_node(
|
||||
tree.clone(),
|
||||
(
|
||||
edge[0],
|
||||
Rc::new(RefCell::new(TreeNode::new(edge[1]))),
|
||||
edge[2],
|
||||
),
|
||||
);
|
||||
ids.push(edge[1]);
|
||||
known_nodes.push((tree, ids));
|
||||
}
|
||||
(None, Some(chi)) => {
|
||||
let (tree, mut ids) = chi;
|
||||
let mut root_node = TreeNode::new(edge[0]);
|
||||
if edge[2] == 1 {
|
||||
root_node.left = Some(tree);
|
||||
} else {
|
||||
root_node.right = Some(tree);
|
||||
}
|
||||
|
||||
ids.push(edge[0]);
|
||||
known_nodes.push((Rc::new(RefCell::new(root_node)), ids));
|
||||
}
|
||||
(Some(parent_data), Some(child_data)) => {
|
||||
println!(
|
||||
"Found connecting edge: \n\t Parent {:?} \n\t child {:?} \n \t edge: {:?}",
|
||||
parent_data.clone(),
|
||||
child_data.clone(),
|
||||
edge
|
||||
);
|
||||
let (parent_tree, mut parent_ids) = parent_data;
|
||||
let (child_tree, mut child_ids) = child_data.to_owned();
|
||||
add_node(parent_tree.clone(), (edge[0], child_tree, edge[2]));
|
||||
parent_ids.append(&mut child_ids);
|
||||
known_nodes.push((parent_tree, parent_ids));
|
||||
}
|
||||
}
|
||||
}
|
||||
println!("NODES AT END: {:?}", known_nodes);
|
||||
let (node, _) = known_nodes.pop().unwrap();
|
||||
Some(node)
|
||||
}
|
||||
|
||||
pub fn add_node(root: Rc<RefCell<TreeNode>>, description: (i32, Rc<RefCell<TreeNode>>, i32)) {
|
||||
fn add_child(
|
||||
node: Rc<RefCell<TreeNode>>,
|
||||
parent_id: i32,
|
||||
child: Rc<RefCell<TreeNode>>,
|
||||
is_left: bool,
|
||||
) -> Option<Rc<RefCell<TreeNode>>> {
|
||||
if node.borrow().val == parent_id {
|
||||
if is_left {
|
||||
(*node).borrow_mut().left = Some(child.clone());
|
||||
if node.clone().borrow().left.is_some() {
|
||||
println!("left is some and delete idx {:?}", delete_idx);
|
||||
let left = if delete_idx.is_none() {
|
||||
println!("clone left");
|
||||
(*node.clone()).borrow().left.clone().unwrap()
|
||||
} else {
|
||||
(*node).borrow_mut().right = Some(child.clone());
|
||||
(*node.clone()).borrow_mut().left.take().unwrap()
|
||||
};
|
||||
|
||||
let delete_left = to_delete.iter().any(|x| *x == left.borrow().val);
|
||||
println!(
|
||||
"delete left {:?} -> {:?}",
|
||||
(delete_left, to_delete.clone()),
|
||||
left.borrow().val
|
||||
);
|
||||
if delete_left {
|
||||
(*node.clone()).borrow_mut().left = None;
|
||||
}
|
||||
|
||||
return Some(child);
|
||||
}
|
||||
|
||||
if let Some(ref left) = node.borrow().left {
|
||||
if let Some(child) = add_child(left.clone(), parent_id, child.clone(), is_left) {
|
||||
return Some(child);
|
||||
if delete_idx.is_some() && !delete_left {
|
||||
root_of_forrest.push(Some(left.clone()));
|
||||
}
|
||||
nodes_to_handle.push_front(left.clone());
|
||||
|
||||
println!("now the current node is {:?}", node.clone());
|
||||
}
|
||||
|
||||
if let Some(ref right) = node.borrow().right {
|
||||
if let Some(child) = add_child(right.clone(), parent_id, child, is_left) {
|
||||
return Some(child);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
add_child(root, description.0, description.1, description.2 == 1);
|
||||
}
|
||||
|
||||
pub fn add_node_v1(root: Rc<RefCell<TreeNode>>, description: (i32, i32, i32)) {
|
||||
fn add_child(
|
||||
node: Rc<RefCell<TreeNode>>,
|
||||
parent_id: i32,
|
||||
child_id: i32,
|
||||
is_left: bool,
|
||||
) -> Option<Rc<RefCell<TreeNode>>> {
|
||||
if node.borrow().val == parent_id {
|
||||
if is_left {
|
||||
(*node).borrow_mut().left = Some(Rc::new(RefCell::new(TreeNode::new(child_id))));
|
||||
if node.clone().borrow().right.is_some() {
|
||||
let right = if delete_idx.is_none() {
|
||||
(*node.clone()).borrow().right.clone().unwrap()
|
||||
} else {
|
||||
(*node).borrow_mut().right = Some(Rc::new(RefCell::new(TreeNode::new(child_id))));
|
||||
(*node.clone()).borrow_mut().right.take().unwrap()
|
||||
};
|
||||
|
||||
let delete_right = to_delete.iter().any(|x| *x == right.borrow().val);
|
||||
println!(
|
||||
"delete right ) {:?} -> {:?}",
|
||||
(delete_right, to_delete.clone()),
|
||||
right.borrow().val
|
||||
);
|
||||
if delete_right {
|
||||
(*node.clone()).borrow_mut().right = None;
|
||||
}
|
||||
|
||||
return Some(Rc::new(RefCell::new(TreeNode::new(child_id))));
|
||||
}
|
||||
|
||||
if let Some(ref left) = node.borrow().left {
|
||||
if let Some(child) = add_child(left.clone(), parent_id, child_id, is_left) {
|
||||
return Some(child);
|
||||
if delete_idx.is_some() && !to_delete.iter().any(|x| *x == right.clone().borrow().val) {
|
||||
root_of_forrest.push(Some(right.clone()));
|
||||
}
|
||||
nodes_to_handle.push_front(right.clone());
|
||||
}
|
||||
|
||||
if let Some(ref right) = node.borrow().right {
|
||||
if let Some(child) = add_child(right.clone(), parent_id, child_id, is_left) {
|
||||
return Some(child);
|
||||
}
|
||||
if let Some(i) = delete_idx {
|
||||
to_delete.remove(i);
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
add_child(root, description.0, description.1, description.2 == 1);
|
||||
root_of_forrest
|
||||
}
|
||||
|
||||
@ -299,6 +299,23 @@ pub fn test_big_random_wiggle(count: usize) -> (Option<Rc<RefCell<TreeNode>>>, i
|
||||
(some_node!(node), (count * 11) as i32)
|
||||
}
|
||||
|
||||
pub fn full_tree_level(level: usize, id_start: i32) -> Option<Rc<RefCell<TreeNode>>> {
|
||||
match level {
|
||||
0 => some_node!(TreeNode::new(id_start)),
|
||||
1 => {
|
||||
let mut root = TreeNode::new(id_start);
|
||||
add_child_vals!(root, id_start + 1, id_start + 2);
|
||||
some_node!(root)
|
||||
}
|
||||
x => {
|
||||
let mut root = TreeNode::new(id_start);
|
||||
let subt_tree_size = 1 << x; // one too much, but includes now the root node ¯\_(ツ)_/¯
|
||||
root.borrow_mut().left = full_tree_level(x - 1, id_start + 1);
|
||||
root.borrow_mut().right = full_tree_level(x - 1, id_start + subt_tree_size);
|
||||
some_node!(root)
|
||||
}
|
||||
}
|
||||
}
|
||||
/* helper */
|
||||
fn generate_unique_nums(count: usize, range: std::ops::Range<usize>) -> Vec<usize> {
|
||||
let mut rng = rand::thread_rng();
|
||||
|
||||
113
src/tree_nodes/1110DeleteNodesAndReturn.rs
Normal file
113
src/tree_nodes/1110DeleteNodesAndReturn.rs
Normal file
@ -0,0 +1,113 @@
|
||||
pub fn del_nodes(
|
||||
root: Option<Rc<RefCell<TreeNode>>>,
|
||||
mut to_delete: Vec<i32>,
|
||||
) -> Vec<Option<Rc<RefCell<TreeNode>>>> {
|
||||
let Some(root_node) = root else {
|
||||
return Vec::new();
|
||||
};
|
||||
let root_val = root_node.borrow().val;
|
||||
let mut root_of_forrest = if !to_delete.iter().any(|x| *x == root_val) {
|
||||
vec![Some(root_node.clone())]
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
let mut nodes_to_handle = VecDeque::new();
|
||||
nodes_to_handle.push_front(root_node);
|
||||
|
||||
while let Some(node) = nodes_to_handle.pop_back() {
|
||||
let node_val = node.borrow().val;
|
||||
let delete_idx = to_delete
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|(_, x)| **x == node_val)
|
||||
.map(|(i, _)| i);
|
||||
|
||||
if node.clone().borrow().left.is_some() {
|
||||
let left = (*node).clone().borrow().left.clone().unwrap();
|
||||
if delete_idx.is_some() && !!to_delete.iter().any(|x| *x == left.clone().borrow().val) {
|
||||
root_of_forrest.push(Some(left.clone()));
|
||||
}
|
||||
nodes_to_handle.push_front(left.clone());
|
||||
}
|
||||
if node.clone().borrow().right.is_some() {
|
||||
let right = (*node).clone().borrow().right.clone().unwrap();
|
||||
if delete_idx.is_some() && !!to_delete.iter().any(|x| *x == right.clone().borrow().val)
|
||||
{
|
||||
root_of_forrest.push(Some(right.clone()));
|
||||
}
|
||||
nodes_to_handle.push_front(right.clone());
|
||||
}
|
||||
if let Some(i) = delete_idx {
|
||||
to_delete.remove(i);
|
||||
}
|
||||
}
|
||||
root_of_forrest
|
||||
}
|
||||
|
||||
/* v2 - actually remmove from tree instead of just returning root nodes */
|
||||
|
||||
pub fn del_nodes(
|
||||
root: Option<Rc<RefCell<TreeNode>>>,
|
||||
mut to_delete: Vec<i32>,
|
||||
) -> Vec<Option<Rc<RefCell<TreeNode>>>> {
|
||||
let Some(root_node) = root else {
|
||||
return Vec::new();
|
||||
};
|
||||
let root_val = root_node.borrow().val;
|
||||
let mut root_of_forrest = if !to_delete.iter().any(|x| *x == root_val) {
|
||||
vec![Some(root_node.clone())]
|
||||
} else {
|
||||
Vec::new()
|
||||
};
|
||||
let mut nodes_to_handle = VecDeque::new();
|
||||
nodes_to_handle.push_front(root_node);
|
||||
|
||||
while let Some(node) = nodes_to_handle.pop_back() {
|
||||
let node_val = node.borrow().val;
|
||||
let delete_idx = to_delete
|
||||
.iter()
|
||||
.enumerate()
|
||||
.find(|(_, x)| **x == node_val)
|
||||
.map(|(i, _)| i);
|
||||
|
||||
if node.clone().borrow().left.is_some() {
|
||||
let left = if delete_idx.is_none() {
|
||||
(*node.clone()).borrow().left.clone().unwrap()
|
||||
} else {
|
||||
(*node.clone()).borrow_mut().left.take().unwrap()
|
||||
};
|
||||
|
||||
let delete_left = to_delete.iter().any(|x| *x == left.borrow().val);
|
||||
if delete_left {
|
||||
(*node.clone()).borrow_mut().left = None;
|
||||
}
|
||||
|
||||
if delete_idx.is_some() && !delete_left {
|
||||
root_of_forrest.push(Some(left.clone()));
|
||||
}
|
||||
nodes_to_handle.push_front(left.clone());
|
||||
}
|
||||
if node.clone().borrow().right.is_some() {
|
||||
let right = if delete_idx.is_none() {
|
||||
(*node.clone()).borrow().right.clone().unwrap()
|
||||
} else {
|
||||
(*node.clone()).borrow_mut().right.take().unwrap()
|
||||
};
|
||||
|
||||
let delete_right = to_delete.iter().any(|x| *x == right.borrow().val);
|
||||
|
||||
if delete_right {
|
||||
(*node.clone()).borrow_mut().right = None;
|
||||
}
|
||||
|
||||
if delete_idx.is_some() && !to_delete.iter().any(|x| *x == right.clone().borrow().val) {
|
||||
root_of_forrest.push(Some(right.clone()));
|
||||
}
|
||||
nodes_to_handle.push_front(right.clone());
|
||||
}
|
||||
if let Some(i) = delete_idx {
|
||||
to_delete.remove(i);
|
||||
}
|
||||
}
|
||||
root_of_forrest
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user