Add BST and differentiate Stack.

This commit is contained in:
Jesse Brault 2024-11-22 15:41:29 -06:00
parent 434881f877
commit c0dc9e794e
3 changed files with 143 additions and 49 deletions

76
src/bst.rs Normal file
View File

@ -0,0 +1,76 @@
use std::cmp::Ordering::*;
#[derive(Debug)]
pub struct BinarySearchTree<T: Ord> {
root: Option<Box<Node<T>>>,
}
#[derive(Debug)]
struct Node<T> {
data: T,
left: Option<Box<Node<T>>>,
right: Option<Box<Node<T>>>,
}
impl<T: Ord> BinarySearchTree<T> {
pub fn new() -> BinarySearchTree<T> {
BinarySearchTree { root: None }
}
pub fn insert(&mut self, data: T) {
match self.root.take() {
None => {
self.root = Some(Box::new(Node {
data,
left: None,
right: None,
}))
}
Some(mut root) => {
root.insert_child(data);
self.root = Some(root);
}
}
}
pub fn find(&mut self, data: T) -> Option<T> {
self.root.take().map(|mut root| root.find(data))?
}
}
impl<T: Ord> Node<T> {
fn new(data: T) -> Self {
Node {
data,
left: None,
right: None,
}
}
fn insert_child(&mut self, data: T) {
match self.data.cmp(&data) {
Less => match self.right.take() {
None => self.right = Some(Box::new(Node::new(data))),
Some(mut right) => {
right.insert_child(data);
self.right = Some(right);
}
},
Equal | Greater => match self.left.take() {
None => self.left = Some(Box::new(Node::new(data))),
Some(mut left) => {
left.insert_child(data);
self.left = Some(left);
}
},
}
}
fn find(&mut self, data: T) -> Option<T> {
match self.data.cmp(&data) {
Less => self.right.take().map(|mut right| right.find(data))?,
Equal => Some(data),
Greater => self.left.take().map(|mut left| left.find(data))?,
}
}
}

View File

@ -1,3 +1,9 @@
mod bst;
mod stack;
use bst::BinarySearchTree;
use stack::Stack;
struct Greeter {
greeting: &'static str,
}
@ -12,59 +18,28 @@ impl Greeter {
}
}
struct LinkedList<T> {
head: Link<T>,
}
enum Link<T> {
Empty,
More(Box<Node<T>>),
}
struct Node<T> {
data: T,
next: Link<T>,
}
impl<T> LinkedList<T> {
fn new() -> Self {
LinkedList { head: Link::Empty }
}
fn push(&mut self, data: T) {
self.head = Link::More(Box::new(Node {
data,
next: std::mem::replace(&mut self.head, Link::Empty),
}));
}
fn pop(&mut self) -> Option<T> {
match std::mem::replace(&mut self.head, Link::Empty) {
Link::Empty => None,
Link::More(node) => {
self.head = node.next;
Some(node.data)
}
}
}
}
impl<T> Iterator for LinkedList<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
self.pop()
}
}
fn main() {
Greeter::new("Hello, Jesse!").greet();
let mut my_linked_list = LinkedList::new();
my_linked_list.push(Greeter::new("Hello"));
my_linked_list.push(Greeter::new("Beautiful"));
my_linked_list.push(Greeter::new("World"));
let mut my_stack = Stack::new();
my_stack.push(Greeter::new("Hello"));
my_stack.push(Greeter::new("Beautiful"));
my_stack.push(Greeter::new("World"));
for greeter in my_linked_list {
for greeter in my_stack {
greeter.greet();
}
// BST
let mut bst = BinarySearchTree::new();
bst.insert(1);
bst.insert(2);
bst.insert(3);
println!("{:?}", bst);
bst.insert(0);
println!("{:?}", bst);
println!("find result: {:?}", bst.find(0));
}

43
src/stack.rs Normal file
View File

@ -0,0 +1,43 @@
pub struct Stack<T> {
head: Link<T>,
}
enum Link<T> {
Empty,
More(Box<Node<T>>),
}
struct Node<T> {
data: T,
next: Link<T>,
}
impl<T> Stack<T> {
pub fn new() -> Self {
Stack { head: Link::Empty }
}
pub fn push(&mut self, data: T) {
self.head = Link::More(Box::new(Node {
data,
next: std::mem::replace(&mut self.head, Link::Empty),
}));
}
pub fn pop(&mut self) -> Option<T> {
match std::mem::replace(&mut self.head, Link::Empty) {
Link::Empty => None,
Link::More(node) => {
self.head = node.next;
Some(node.data)
}
}
}
}
impl<T> Iterator for Stack<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
self.pop()
}
}