parent
fb05405c9d
commit
4ed4c4edf8
@ -1,6 +1,8 @@
|
|||||||
#![feature(test)]
|
#![feature(test)]
|
||||||
extern crate test;
|
extern crate test;
|
||||||
|
|
||||||
|
mod linked;
|
||||||
|
mod linked_im;
|
||||||
mod search;
|
mod search;
|
||||||
mod tree;
|
mod tree;
|
||||||
mod vec_basic;
|
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);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue