Giter VIP home page Giter VIP logo

bst-rs's Introduction

bst-rs

build crate.io downloads license

Recursive & Iterative Binary Search Tree Implementations within Rust

Table of Contents

About

This crate contains Recursive & Iterative Binary Search Tree Implementations. All common operations are included along with common traversal iterators.

All elements within the Binary Search Trees must implement the Ord trait.

It is also important to note that RecursiveBST is more likely to blow the stack. For more information on why that is the case, please have a look at The Story of Tail Call Optimizations in Rust.

Personal Goals

I have made this library with the personal goals of learning and solidifying concepts such as ownership, borrowing , generics and lifetimes. I cannot promise that the implementations are particularly efficient, or if they are, it was not at the forefront of my mind.

That being said, there are some areas I would love to improve upon which include:

  • Write idiomatic code.
  • Effectively use macro_rules! to reduce large portions of repetitive code.
  • Implement a pretty_print() function to display the binary search trees nicely.
  • Implementing the Drop trait for iterative node cleanup.
  • Pre-allocating space on the heap for nodes to reduce inefficiency of inserts.

I'm more than happy to accept (and encourage) contributions if anyone is kind enough to do so. (Please look at CONTRIBUTING!)

Quick Start

use bst_rs::{BinarySearchTree, IterativeBST, RecursiveBST};

// Create new empty binary search trees
let mut iterative_bst = IterativeBST::new();
assert!(iterative_bst.is_empty());

let mut recursive_bst = RecursiveBST::new();
assert!(recursive_bst.is_empty());

// Insert elements (no duplicates are allowed)
iterative_bst.insert(10);
iterative_bst.insert(10);   // Element is not inserted
iterative_bst.insert(5);
iterative_bst.insert(2);
iterative_bst.insert(15);
iterative_bst.insert(25);
assert_eq!(iterative_bst.size(), 5);

recursive_bst.insert(10);
recursive_bst.insert(10);   // Element is not inserted
recursive_bst.insert(5);
recursive_bst.insert(2);
recursive_bst.insert(15);
recursive_bst.insert(25);
assert_eq!(recursive_bst.size(), 5);

// Check if element exists
assert!(iterative_bst.contains(&5));    // true
assert!(!iterative_bst.contains(&0));   // false

assert!(recursive_bst.contains(&5));    // true
assert!(!recursive_bst.contains(&0));   // false

// Remove elements
iterative_bst.remove(&10);
iterative_bst.remove(&50); // No change to tree as element does not exist
assert_eq!(iterative_bst.size(), 4);

recursive_bst.remove(&10);
recursive_bst.remove(&50); // No change to tree as element does not exist
assert_eq!(recursive_bst.size(), 4);

// Get height of tree
assert_eq!(iterative_bst.height(), Some(2));
assert_eq!(recursive_bst.height(), Some(2));

// Get minimum element of tree
assert_eq!(iterative_bst.min(), Some(&2));
assert_eq!(recursive_bst.min(), Some(&2));

// Get maximum element of tree
assert_eq!(iterative_bst.max(), Some(&25));
assert_eq!(recursive_bst.max(), Some(&25));

// Retrieve reference to element in tree
assert_eq!(iterative_bst.retrieve(&5), Some(&5));
assert_eq!(iterative_bst.retrieve(&100), None); // Element does not exist so None is returned
assert_eq!(recursive_bst.retrieve(&5), Some(&5));
assert_eq!(recursive_bst.retrieve(&100), None); // Element does not exist so None is returned

// View pre-order, in-order, post-order and level-order traversals
assert_eq!(iterative_bst.pre_order_vec(), vec![&15, &5, &2, &25]);
assert_eq!(iterative_bst.in_order_vec(), vec![&2, &5, &15, &25]);
assert_eq!(iterative_bst.post_order_vec(), vec![&2, &5, &25, &15]);
assert_eq!(iterative_bst.level_order_vec(), vec![&15, &5, &25, &2]);

assert_eq!(recursive_bst.pre_order_vec(), vec![&15, &5, &2, &25]);
assert_eq!(recursive_bst.in_order_vec(), vec![&2, &5, &15, &25]);
assert_eq!(recursive_bst.post_order_vec(), vec![&2, &5, &25, &15]);
assert_eq!(recursive_bst.level_order_vec(), vec![&15, &5, &25, &2]);

// Compare equality/in-equality of trees
assert_eq!(iterative_bst.asc_order_vec(), recursive_bst.asc_order_vec());
assert_ne!(iterative_bst, IterativeBST::new());
assert_ne!(recursive_bst, RecursiveBST::new());

License

MIT License

Contributing

Please read the CONTRIBUTING.md before contributing! (Thank you!)

Inspiration

The book Learn Rust With Entirely Too Many Linked Lists inspired me to try and implement Binary Search Trees within the language. I had also been wanting to create my first library for other crates to use.

bst-rs's People

Contributors

nassersaazi avatar nyxkrage avatar sgoudham avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

Forkers

nyxkrage

bst-rs's Issues

[v0.1.1] -> Add retrieval methods for Predecessor & Successor

Context

Common operations surrounding BST's are retrieving Predecessor & Successor Successors.
The definitions of both terms are as follows:

Successor

The Successor can be thought of as the smallest value greater than the value of the given node.

E.G. Given a tree that looks like:

graph TB;
    A((8))-->B((3))
    A-->C((10))
    B-->D((1))
    B-->E((6))
    C-->F((9))
    C-->G((14))
    E-->H((4))
    E-->I((7))
Loading

The Successor of 3 is 4.

Predecessor

The Predecessor can be thought of as the greatest value less than the value of the given node.

E.G Given a tree that looks like:

graph TB;
    A((8))-->B((3))
    A-->C((10))
    B-->D((1))
    B-->E((6))
    C-->F((9))
    C-->G((14))
    E-->H((4))
    E-->I((7))
Loading

The Predecessor of 8 is 7.

What We Need To Do

Successor & Predecessor retrieval methods should implemented as part of the BinarySearchTree trait and implemented within RecursiveBST & IterativeBST

[v0.1.1] -> Add bst![] macro defaulting to IterativeBST

Motivation

Users can currently only use IterativeBST & RecursiveBST structs directly for creating BinarySearchTrees. We should streamline this process by implementing a declarative macro that can instantiate the tree for them that defaults to the IterativeBST implementation.

E.G Given the user wants to represent the following tree:

graph TB;
    A((8))-->B((3))
    A-->C((10))
    B-->D((1))
    B-->E((6))
    C-->F((9))
	C-->G((15))
Loading

The code could look like:

let mut bst = bst![8, 10, 9, 15, 3, 6, 1];

What We Need To Do

Add bst![] macro that defaults to the IterativeBST implementation.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.