linked lists

master
Jason Staten 6 years ago
parent fb05405c9d
commit 4ed4c4edf8

@ -1,6 +1,8 @@
#![feature(test)]
extern crate test;
mod linked;
mod linked_im;
mod search;
mod tree;
mod vec_basic;

@ -0,0 +1,81 @@
use std::iter::FromIterator;
use std::mem;
#[allow(unused)]
#[derive(Debug, PartialEq)]
enum Node<T> {
Cons(T, Box<Node<T>>),
Nil,
}
impl<T> Node<T> {
fn iter(self) -> Iter<T> {
Iter { node: self }
}
}
impl<'a, T> FromIterator<T> for Node<T> {
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
let mut output = Node::Nil;
for x in iter {
output = Node::Cons(x, Box::new(output));
}
output
}
}
struct Iter<T> {
node: Node<T>,
}
impl<T> Iterator for Iter<T> {
type Item = T;
fn next(&mut self) -> Option<Self::Item> {
let old_node = mem::replace(&mut self.node, Node::Nil);
match old_node {
Node::Cons(head, tail) => {
self.node = *tail;
Some(head)
}
Node::Nil => None,
}
}
}
#[cfg(test)]
mod test {
use self::Node::*;
use super::*;
#[test]
fn test_can_construct() {
if let Cons(head, tail) = Cons("home", Box::new(Nil)) {
assert_eq!(head, "home");
assert_eq!(tail, Box::new(Nil));
} else {
assert!(false, "Not a Cons")
}
}
#[test]
fn test_from_iter() {
let expected = Cons(1, Box::new(Cons(2, Box::new(Cons(3, Box::new(Nil))))));
let result = Node::from_iter(vec![3, 2, 1]);
assert_eq!(result, expected);
}
#[test]
fn test_iterate() {
let list = Cons(1, Box::new(Cons(2, Box::new(Cons(3, Box::new(Nil))))));
let i = list.iter();
let result: Vec<i32> = i.collect();
let expected = vec![1, 2, 3];
assert_eq!(result, expected);
}
}

@ -0,0 +1,104 @@
use std::iter::FromIterator;
use std::rc::Rc;
type Link<T> = Option<Rc<Node<T>>>;
struct Node<T> {
value: T,
next: Link<T>,
}
struct LinkedList<T> {
head: Link<T>,
}
impl<T> LinkedList<T> {
fn new() -> LinkedList<T> {
LinkedList { head: Option::None }
}
fn append(self, el: T) -> LinkedList<T> {
LinkedList {
head: Option::Some(Rc::new(Node {
value: el,
next: self.head,
})),
}
}
fn head(&self) -> Option<&T> {
self.head.as_ref().map(|node| &node.value)
}
fn tail(&self) -> LinkedList<T> {
LinkedList {
head: self.head.as_ref().and_then(|node| node.next.clone()),
}
}
}
impl<'a, T> FromIterator<T> for LinkedList<T> {
fn from_iter<I: IntoIterator<Item = T>>(source: I) -> Self {
source
.into_iter()
.fold(LinkedList::new(), LinkedList::append)
}
}
#[cfg(test)]
mod test {
use super::LinkedList;
use std::iter::FromIterator;
#[test]
fn test_append() {
let list = LinkedList::<u32> { head: Option::None };
let appended = list.append(42);
match appended.head {
Option::Some(node) => assert_eq!((*node).value, 42),
_ => assert!(false, "was not Some"),
}
}
#[test]
fn test_append_str() {
let list = LinkedList::<&str> { head: Option::None };
let appended = list.append("one").append("two").append("three");
match appended.head {
Option::Some(node) => assert_eq!((*node).value, "three"),
_ => assert!(false, "was not Some"),
}
}
#[test]
fn test_head() {
let list = LinkedList::<&str> { head: Option::None };
let appended = list.append("one").append("two").append("three");
match appended.head() {
Option::Some(val) => assert_eq!(val, &"three"),
_ => assert!(false, "was not Some"),
}
}
#[test]
fn test_tail() {
let list = LinkedList::<&str> { head: Option::None };
let appended = list.append("one").append("two").append("three");
match appended.tail().head() {
Option::Some(val) => assert_eq!(val, &"two"),
_ => assert!(false, "was not Some"),
}
}
#[test]
fn test_from_iter() {
let list = LinkedList::from_iter(vec![1, 2, 3]);
let h1 = list.head().unwrap().clone();
let h2 = list.tail().head().unwrap().clone();
let h3 = list.tail().tail().head().unwrap().clone();
assert_eq!(h1, 3);
assert_eq!(h2, 2);
assert_eq!(h3, 1);
}
}

@ -1,3 +1,4 @@
#![allow(unused)]
#[allow(unused_imports)]
extern crate test;
use test::Bencher;

@ -1,3 +1,4 @@
#![allow(unused)]
#[derive(Debug)]
struct Node<'a>(&'a str, Vec<Node<'a>>);

@ -1,3 +1,4 @@
#![allow(unused)]
#[allow(unused_imports)]
extern crate test;
use test::Bencher;

Loading…
Cancel
Save