addedd delete node and return

This commit is contained in:
hendrik 2024-07-18 18:15:13 +02:00
parent 007ecbc980
commit deb0c8d899
4 changed files with 274 additions and 200 deletions

68
Cargo.lock generated
View File

@ -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"

View File

@ -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
}

View File

@ -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();

View 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
}