added simple linked list
This commit is contained in:
@@ -0,0 +1 @@
|
|||||||
|
/target
|
||||||
Generated
+7
@@ -0,0 +1,7 @@
|
|||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linked-list"
|
||||||
|
version = "0.1.0"
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
[package]
|
||||||
|
name = "linked-list"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
+102
@@ -0,0 +1,102 @@
|
|||||||
|
|
||||||
|
struct List { head: Option<Box<Node>>, len: usize }
|
||||||
|
struct Node {
|
||||||
|
value: u32,
|
||||||
|
next: Option<Box<Node>>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl List {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
List { head: None, len: 0}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn append(&mut self, val: u32) {
|
||||||
|
let slot = self.walk(self.len);
|
||||||
|
*slot = Some(Box::new(Node{value: val, next: None}));
|
||||||
|
self.len += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn insert(&mut self, val: u32, index: usize) {
|
||||||
|
let slot = self.walk(index);
|
||||||
|
let rest = slot.take();
|
||||||
|
*slot = Some(Box::new(Node { value: val, next: rest }));
|
||||||
|
self.len += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn remove(&mut self, index: usize) -> Option<u32> {
|
||||||
|
if index >= self.len {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
let slot = self.walk(index);
|
||||||
|
let removed = slot.take()?;
|
||||||
|
*slot = removed.next;
|
||||||
|
self.len -= 1;
|
||||||
|
Some(removed.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
// walk returns the entry at index
|
||||||
|
fn walk(&mut self, index: usize) -> &mut Option<Box<Node>> {
|
||||||
|
let mut iter = &mut self.head;
|
||||||
|
for _ in 0..index {
|
||||||
|
match iter {
|
||||||
|
Some(node) => iter = &mut node.next,
|
||||||
|
None => break,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
iter
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn as_vec(&self) -> Vec<u32> {
|
||||||
|
let mut result = Vec::new();
|
||||||
|
let mut i = &self.head;
|
||||||
|
while let Some(node) = i {
|
||||||
|
result.push(node.value);
|
||||||
|
i = &node.next;
|
||||||
|
}
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_empty(&self) -> bool {
|
||||||
|
self.len == 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("use cargo test");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_list() {
|
||||||
|
let mut l = List::new();
|
||||||
|
l.append(1);
|
||||||
|
l.append(2);
|
||||||
|
l.append(3);
|
||||||
|
l.append(4);
|
||||||
|
assert_eq!(l.as_vec(), vec![1,2,3,4]);
|
||||||
|
|
||||||
|
l.remove(2);
|
||||||
|
assert_eq!(l.as_vec(), vec![1,2,4]);
|
||||||
|
l.remove(2);
|
||||||
|
assert_eq!(l.as_vec(), vec![1,2]);
|
||||||
|
l.remove(2); // too far, no removal
|
||||||
|
assert_eq!(l.as_vec(), vec![1,2]);
|
||||||
|
|
||||||
|
l.insert(5, 1);
|
||||||
|
assert_eq!(l.as_vec(), vec![1,5,2]);
|
||||||
|
l.insert(6, 3);
|
||||||
|
assert_eq!(l.as_vec(), vec![1,5,2,6]);
|
||||||
|
|
||||||
|
l.remove(0);
|
||||||
|
assert_eq!(l.as_vec(), vec![5,2,6]);
|
||||||
|
l.remove(0);
|
||||||
|
assert_eq!(l.as_vec(), vec![2,6]);
|
||||||
|
l.remove(0);
|
||||||
|
assert_eq!(l.as_vec(), vec![6]);
|
||||||
|
l.remove(0);
|
||||||
|
assert!(l.is_empty());
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user