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