Skip to content

Commit 2c4bccb

Browse files
committed
docs: add linked list examples and benchmarks
1 parent 7a69ce7 commit 2c4bccb

10 files changed

Lines changed: 242 additions & 0 deletions

Cargo.toml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,24 @@ path = "examples/soluciones/vector_insert_sorted.rs"
2525
name = "solution_vector_retain_prefix"
2626
path = "examples/soluciones/vector_retain_prefix.rs"
2727

28+
[[example]]
29+
name = "solution_linked_list_reverse_input"
30+
path = "examples/soluciones/linked_list_reverse_input.rs"
31+
32+
[[example]]
33+
name = "solution_linked_list_move_front_to_back"
34+
path = "examples/soluciones/linked_list_move_front_to_back.rs"
35+
36+
[[example]]
37+
name = "solution_linked_list_remove_every_other"
38+
path = "examples/soluciones/linked_list_remove_every_other.rs"
39+
2840
[[bench]]
2941
name = "vector_bench"
3042
path = "benches/vector_bench.rs"
3143
harness = false
44+
45+
[[bench]]
46+
name = "linked_list_bench"
47+
path = "benches/linked_list_bench.rs"
48+
harness = false

benches/linked_list_bench.rs

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
use rust_data_structures::linked_list::LinkedList;
2+
use rust_data_structures::vector::Vector;
3+
use std::hint::black_box;
4+
use std::time::{Duration, Instant};
5+
6+
const SIZE: usize = 20_000;
7+
8+
fn main() {
9+
println!("linked list benchmark (manual, std::time::Instant)");
10+
println!("size: {SIZE}");
11+
println!("push_front: {:?}", bench_push_front());
12+
println!("push_back: {:?}", bench_push_back());
13+
println!("pop_front: {:?}", bench_pop_front());
14+
println!("iterate linked list: {:?}", bench_linked_list_iteration());
15+
println!("iterate vector: {:?}", bench_vector_iteration());
16+
}
17+
18+
fn bench_push_front() -> Duration {
19+
let start = Instant::now();
20+
let mut list = LinkedList::new();
21+
22+
for value in 0..SIZE {
23+
list.push_front(black_box(value));
24+
}
25+
26+
black_box(list.len());
27+
start.elapsed()
28+
}
29+
30+
fn bench_push_back() -> Duration {
31+
let start = Instant::now();
32+
let mut list = LinkedList::new();
33+
34+
for value in 0..SIZE {
35+
list.push_back(black_box(value));
36+
}
37+
38+
black_box(list.len());
39+
start.elapsed()
40+
}
41+
42+
fn bench_pop_front() -> Duration {
43+
let mut list = LinkedList::new();
44+
for value in 0..SIZE {
45+
list.push_back(value);
46+
}
47+
48+
let start = Instant::now();
49+
while let Some(value) = list.pop_front() {
50+
black_box(value);
51+
}
52+
53+
start.elapsed()
54+
}
55+
56+
fn bench_linked_list_iteration() -> Duration {
57+
let mut list = LinkedList::new();
58+
for value in 0..SIZE {
59+
list.push_front(value);
60+
}
61+
62+
let start = Instant::now();
63+
let sum: usize = list.iter().copied().map(black_box).sum();
64+
65+
black_box(sum);
66+
start.elapsed()
67+
}
68+
69+
fn bench_vector_iteration() -> Duration {
70+
let mut vector = Vector::with_capacity(SIZE);
71+
for value in 0..SIZE {
72+
vector.push(value);
73+
}
74+
75+
let start = Instant::now();
76+
let sum: usize = vector.iter().copied().map(black_box).sum();
77+
78+
black_box(sum);
79+
start.elapsed()
80+
}

diagrams/02-linked-list.mmd

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
flowchart LR
2+
title["Linked List: nodos enlazados por ownership"]
3+
4+
list["LinkedList<br/>head + len"]
5+
node0["Node A<br/>value + next"]
6+
node1["Node B<br/>value + next"]
7+
node2["Node C<br/>value + next"]
8+
none["None"]
9+
10+
list --> node0
11+
node0 --> node1
12+
node1 --> node2
13+
node2 --> none
14+
15+
push_front["push_front(X)<br/>nuevo nodo apunta al head anterior"]
16+
push_front --> list
17+
18+
push_back["push_back(X)<br/>recorre hasta next = None"]
19+
push_back --> node2

examples/linked_list_advanced.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
use rust_data_structures::linked_list::LinkedList;
2+
3+
fn main() {
4+
let mut list = LinkedList::new();
5+
6+
for value in 1..=5 {
7+
list.push_back(value);
8+
}
9+
10+
let removed = list.remove(2).expect("index 2 exists");
11+
let remaining = list.iter().copied().collect::<Vec<_>>();
12+
13+
println!("removido: {removed}");
14+
println!("restantes: {remaining:?}");
15+
}

examples/linked_list_basic.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
use rust_data_structures::linked_list::LinkedList;
2+
3+
fn main() {
4+
let mut pages = LinkedList::new();
5+
6+
pages.push_front("capitulo-vector");
7+
pages.push_front("prefacio");
8+
9+
println!("primera pagina: {}", pages.front().unwrap());
10+
println!("ultima pagina: {}", pages.back().unwrap());
11+
println!("paginas: {}", pages.len());
12+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
use rust_data_structures::linked_list::LinkedList;
2+
3+
fn main() {
4+
let mut queue = LinkedList::new();
5+
6+
queue.push_back("validar README");
7+
queue.push_back("revisar doctests");
8+
queue.push_back("actualizar ROADMAP");
9+
10+
while let Some(task) = queue.pop_front() {
11+
println!("procesando: {task}");
12+
}
13+
}

examples/linked_list_real_case.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
use rust_data_structures::linked_list::LinkedList;
2+
3+
fn main() {
4+
let mut retry_queue = LinkedList::new();
5+
6+
retry_queue.push_back(Job::new("sync-calendar", 1));
7+
retry_queue.push_back(Job::new("send-webhook", 2));
8+
retry_queue.push_back(Job::new("rebuild-index", 1));
9+
10+
while let Some(job) = retry_queue.pop_front() {
11+
println!("ejecutando {} (intento {})", job.name, job.attempt);
12+
}
13+
}
14+
15+
struct Job {
16+
name: &'static str,
17+
attempt: u8,
18+
}
19+
20+
impl Job {
21+
fn new(name: &'static str, attempt: u8) -> Self {
22+
Self { name, attempt }
23+
}
24+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
use rust_data_structures::linked_list::LinkedList;
2+
3+
fn main() {
4+
let mut list = LinkedList::new();
5+
list.push_back("a");
6+
list.push_back("b");
7+
list.push_back("c");
8+
9+
move_front_to_back(&mut list);
10+
11+
let values = list.iter().copied().collect::<Vec<_>>();
12+
assert_eq!(values, vec!["b", "c", "a"]);
13+
println!("{values:?}");
14+
}
15+
16+
fn move_front_to_back<T>(list: &mut LinkedList<T>) {
17+
if let Some(value) = list.pop_front() {
18+
list.push_back(value);
19+
}
20+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
use rust_data_structures::linked_list::LinkedList;
2+
3+
fn main() {
4+
let mut list = LinkedList::new();
5+
for value in 1..=8 {
6+
list.push_back(value);
7+
}
8+
9+
remove_every_other(&mut list);
10+
11+
let values = list.iter().copied().collect::<Vec<_>>();
12+
assert_eq!(values, vec![1, 3, 5, 7]);
13+
println!("{values:?}");
14+
}
15+
16+
fn remove_every_other<T>(list: &mut LinkedList<T>) {
17+
let mut index = 1;
18+
19+
while index < list.len() {
20+
list.remove(index);
21+
index += 1;
22+
}
23+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
use rust_data_structures::linked_list::LinkedList;
2+
3+
fn main() {
4+
let reversed = reverse_with_push_front([1, 2, 3, 4]);
5+
let values = reversed.iter().copied().collect::<Vec<_>>();
6+
7+
assert_eq!(values, vec![4, 3, 2, 1]);
8+
println!("{values:?}");
9+
}
10+
11+
fn reverse_with_push_front(values: impl IntoIterator<Item = i32>) -> LinkedList<i32> {
12+
let mut list = LinkedList::new();
13+
14+
for value in values {
15+
list.push_front(value);
16+
}
17+
18+
list
19+
}

0 commit comments

Comments
 (0)