Skip to content

Commit

Permalink
Merge pull request #9 from azizkayumov/connected
Browse files Browse the repository at this point in the history
Connected
  • Loading branch information
azizkayumov committed Sep 27, 2023
2 parents d6ee332 + 04a6c63 commit 159e55c
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 2 deletions.
5 changes: 3 additions & 2 deletions src/access.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::{

// constructs a path from the root to the node at idx
pub fn access(forest: &mut Vec<Node>, node_idx: usize) {
assert!(node_idx < forest.len(), "access: node_idx out of bounds");
splay(forest, node_idx);

if let Some(right_idx) = forest[node_idx].right {
Expand Down Expand Up @@ -36,15 +37,15 @@ mod tests {
}

#[test]
pub fn access_base_case() {
pub fn base_case() {
// access a single node, should do nothing
let mut forest = create_nodes(1);
super::access(&mut forest, 0);
assert!(matches!(forest[0].parent, Parent::Root));
}

#[test]
pub fn access_splay_leaf() {
pub fn access_leaf() {
let mut forest = create_nodes(3);
// '1' has a path pointer to '0', '1' has a right child '2'.
// after access(2), '2' should be the root of the tree:
Expand Down
71 changes: 71 additions & 0 deletions src/connected.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
use crate::{
access::access,
node::{Node, Parent},
};

pub fn connected(forest: &mut Vec<Node>, v: usize, w: usize) -> bool {
assert!(
v < forest.len() || w < forest.len(),
"splay: node_idx out of bounds"
);
access(forest, v); // v is now the root of the tree
access(forest, w);
// if v is not the root of the tree anymore, then v and w are connected:
!matches!(forest[v].parent, Parent::Root) || v == w
}

#[cfg(test)]
mod tests {
use crate::node::{Node, Parent};

fn create_nodes(n: usize) -> Vec<Node> {
(0..n).map(|i| Node::new(i, 0.0)).collect()
}

#[test]
pub fn base_case() {
// check two nodes, should return false
let mut forest = create_nodes(2);
assert!(!super::connected(&mut forest, 0, 1));
}

#[test]
pub fn connected_with_root() {
// check three nodes, one is root:
// 0
// / \
// 1 2
let mut forest = create_nodes(3);
forest[0].left = Some(1);
forest[0].right = Some(2);
forest[1].parent = Parent::Node(0);
forest[2].parent = Parent::Node(0);

assert!(super::connected(&mut forest, 0, 1));
assert!(super::connected(&mut forest, 0, 2));
assert!(super::connected(&mut forest, 1, 2));
assert!(super::connected(&mut forest, 0, 0));
assert!(super::connected(&mut forest, 1, 1));
assert!(super::connected(&mut forest, 2, 2));
}

#[test]
pub fn connected_with_path_pointers() {
// check two trees that are connected by a path pointer
// 0
// / \
// 1 2
// |
// 3
let mut forest = create_nodes(4);
forest[0].left = Some(1);
forest[0].right = Some(2);
forest[1].parent = Parent::Node(0);
forest[2].parent = Parent::Node(0);
forest[3].parent = Parent::Path(2);

assert!(super::connected(&mut forest, 0, 3));
assert!(super::connected(&mut forest, 1, 3));
assert!(super::connected(&mut forest, 2, 3));
}
}
1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#![allow(dead_code, clippy::module_name_repetitions)] // yes, I want to name my structs with the same name as the file
mod access;
mod connected;
mod node;
mod splay;

0 comments on commit 159e55c

Please sign in to comment.