part 2 except iterator

This commit is contained in:
ridethepig 2023-02-25 10:41:19 +00:00
parent bd5895814e
commit 1e4049204e
2 changed files with 59 additions and 16 deletions

View File

@ -1,24 +1,24 @@
use std::fmt;
use std::option::Option;
pub struct LinkedList {
head: Option<Box<Node>>,
pub struct LinkedList<T> {
head: Option<Box<Node<T>>>,
size: usize,
}
struct Node {
value: u32,
next: Option<Box<Node>>,
struct Node<T> {
value: T,
next: Option<Box<Node<T>>>,
}
impl Node {
pub fn new(value: u32, next: Option<Box<Node>>) -> Node {
impl<T> Node<T> {
pub fn new(value: T, next: Option<Box<Node<T>>>) -> Node<T> {
Node {value: value, next: next}
}
}
impl LinkedList {
pub fn new() -> LinkedList {
impl<T> LinkedList<T> {
pub fn new() -> LinkedList<T> {
LinkedList {head: None, size: 0}
}
@ -30,24 +30,26 @@ impl LinkedList {
self.get_size() == 0
}
pub fn push_front(&mut self, value: u32) {
let new_node: Box<Node> = Box::new(Node::new(value, self.head.take()));
pub fn push_front(&mut self, value: T) {
let new_node: Box<Node<T>> = Box::new(Node::new(value, self.head.take()));
self.head = Some(new_node);
self.size += 1;
}
pub fn pop_front(&mut self) -> Option<u32> {
let node: Box<Node> = self.head.take()?;
pub fn pop_front(&mut self) -> Option<T> {
let node: Box<Node<T>> = self.head.take()?;
self.head = node.next;
self.size -= 1;
Some(node.value)
}
}
impl fmt::Display for LinkedList {
impl<T:fmt::Display> fmt::Display for LinkedList<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut current: &Option<Box<Node>> = &self.head;
let mut current: &Option<Box<Node<T>>> = &self.head;
let mut result = String::new();
loop {
match current {
@ -62,7 +64,7 @@ impl fmt::Display for LinkedList {
}
}
impl Drop for LinkedList {
impl<T> Drop for LinkedList<T> {
fn drop(&mut self) {
let mut current = self.head.take();
while let Some(mut node) = current {
@ -71,5 +73,40 @@ impl Drop for LinkedList {
}
}
impl<T:Clone> Clone for Node<T> {
fn clone(&self) -> Self {
Node::new(self.value.clone(), self.next.clone())
}
}
impl<T:Clone> Clone for LinkedList<T> {
fn clone(&self) -> LinkedList<T> {
let mut copy_list = LinkedList::new();
copy_list.size = self.size;
copy_list.head = self.head.clone();
// tricky recursive clone, Option clone-> Box clone-> Node clone -> Node.next clone(Box clone)
// I tried to implement tail-insertion, but it is impossible to realize that without unsafe...
copy_list
}
}
impl<T:PartialEq> PartialEq for LinkedList<T> {
fn eq(&self, other: &Self) -> bool {
if self.size != other.size {
return false;
}
let mut ptr = & self.head;
let mut ptr_other = & other.head;
while let Some(node) = ptr {
// well, as their size are the same, it's fine to assume that they reach the end at the same time
let node_other = ptr_other.as_ref().unwrap();
if node_other.value != node.value {
return false;
}
ptr = &node.next;
ptr_other = &node_other.next;
}
true
}
}

View File

@ -15,6 +15,12 @@ fn main() {
println!("size: {}", list.get_size());
println!("{}", list.to_string()); // ToString impl for anything impl Display
let mut list2 = list.clone();
println!("Right after clone: list == list2 ?= {}", list == list2);
list2.pop_front();
println!("list2.pop_front: {}", list2);
println!("list == list2 ?= {}", list == list2);
// If you implement iterator trait:
//for val in &list {
// println!("{}", val);