libtree 0.1.0

a crate for general or game tree
Documentation
  • Coverage
  • 100%
    5 out of 5 items documented4 out of 4 items with examples
  • Size
  • Source code size: 84.22 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 2.37 MB This is the summed size of all files generated by rustdoc for all configured targets
  • Links
  • furarox/libtree
    0 0 0
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • furarox

libtree : a crate for game tree

gtree is a crate that implements trees in Rust, taking huge inspirations from Rust with too many linked lists (so it is as useless and stupid as it's inspiration). The main purpose of this crate was to implements tree for game tree needed in a crate for game theory.

Nomenclature

Just a bit of nomemclature to be make my documentation slighty more readable.

  • a node is a set of pointers (one for the father and another collection for the childs) and also stores an element, often abbreviated into elem or el.
  • a tree is composed of two pointers towards nodes :
    • 'current', where you are in the tree.
    • 'root', explicit.
  • the subtree will designates the tree that is rooted at 'current' in a tree.
  • a cursor is another pointer to a node of the tree, but without a root associated.

Showcase

Creation and adding elements

gtree provides the [Tree] structure to create a store a tree, and add new element to it.

use gtree::Tree;
let mut tree = Tree::from_element(1);
tree.push(2);

Navigation

By navigation, we mean moving around 'current' in the tree. But as the term move has already a signication in Rust, we use the term navigation in this crate. Tree supports three type of navigation :

  • navigate_to(idx) which navigates 'current' to its idx child (if possible).
  • ascend() which navigates 'current' to its father (if possible i.e. not at 'root').
  • go_to_root() which navigates 'current' to 'root'.
assert_eq!(tree.peek(), &1);
tree.navigate_to(0);
assert_eq!(tree.peek(), &2);
tree.push(3);
tree.ascend();
assert_eq!(tree.into_vec(), vec![1, 2, 3]);

Joining and splitting

Trees can be joined and splitted. Splitting tree is for the moment the best way to drop unwantted part of the tree.

let mut tree1 = Tree::from_element(1);
tree1.push_iter(vec![2, 3]);
let mut tree2 = Tree::from_element(4);
tree2.push_iter(vec![5, 6]);
tree1.join(tree2, 0);
// exploration is always made in depth first way
assert_eq!(tree1.iter().collect::<Vec<&i32>>(), vec![&1, &4, &5, &6, &2, &3]);
let mut tree2 = tree1.split(0);
assert_eq!(tree2.into_vec(), vec![4, 5, 6]);

Cursors

Cursors are of three differents types and allows concurrent exploration of the tree.

let mut cursor1 = tree1.cursor();
let cursor2 = tree1.cursor();
cursor1.navigate_to(1);
assert_eq!(cursor1.peek(), &3);
assert_eq!(cursor2.peek(), &1);

Subtrees

Most exploration methods when called will only explore the subtree rooted as 'current' (for a tree or a cursor).

let mut tree = Tree::from_element(1);
tree.push_iter(vec![4, 2, 1]);
tree.navigate_to(0);
tree.push_iter(vec![5, 6]);
assert_eq!(tree.iter().collect::<Vec<&i32>>(), vec![&4, &5, &6]);
let mut cursor = tree.cursor_mut();
cursor.ascend();
cursor.navigate_to(1);
cursor.push(10);
assert_eq!(cursor.iter_mut().collect::<Vec<&mut i32>>(), vec![&mut 2, &mut 10]);