Sling Academy
Home/Rust/Rust LinkedList<T> basics: pushing and popping from the front and back

Rust LinkedList basics: pushing and popping from the front and back

Last updated: January 07, 2025

The LinkedList in Rust is a doubly linked list, providing a collection where each element contains pointers to both the next and previous elements. Consequently, it allows for efficient appends and prepends compared to a singly linked list. This article aims to guide you through the basic operations of pushing and popping elements from the front and back of a LinkedList in Rust.

Understanding the LinkedList

A LinkedList is part of Rust's standard library, and it's designed to be used where elements frequently need to be added to or removed from the start or end of the collection. It's not a random-access collection, so indexing into it is not as efficient as with vectors. However, for operations at the ends, it's often ideal.

Creating a LinkedList

To use a LinkedList, you first need to bring it into scope:

use std::collections::LinkedList;

With LinkedList in scope, you can create a new list.

fn main() {
    let mut list: LinkedList<i32> = LinkedList::new();
    println!("Created an empty LinkedList!");
}

Pushing Elements

The push_front method adds an element to the front of the list, while push_back adds it to the back.

Pushing to the Front

Add elements to the beginning of the list using push_front:

fn main() {
    let mut list = LinkedList::new();
    list.push_front(1);
    list.push_front(2);
    println!("List after pushing to the front: {:?}", list);
}

This will output: 
List after pushing to the front: [2, 1]

Pushing to the Back

Add elements to the end using push_back:

fn main() {
    let mut list = LinkedList::new();
    list.push_back(3);
    list.push_back(4);
    println!("List after pushing to the back: {:?}", list);
}

The output will be: 
List after pushing to the back: [3, 4]

Popping Elements

To remove elements from a LinkedList, you have pop_front and pop_back, both of which return an Option<T>.

Popping from the Front

To remove elements from the front:

fn main() {
    let mut list = LinkedList::from([5, 6, 7]);
    list.pop_front();
    println!("List after popping from the front: {:?}", list);
}

The result is: 
List after popping from the front: [6, 7]

Popping from the Back

To remove elements from the end:

fn main() {
    let mut list = LinkedList::from([8, 9, 10]);
    list.pop_back();
    println!("List after popping from the back: {:?}", list);
}

This produces: 
List after popping from the back: [8, 9]

Conclusion

By utilizing methods like push_front, push_back, pop_front, and pop_back, the LinkedList in Rust can efficiently manage operations at both ends of the collection. As seen, using a LinkedList is ideal when your requirement involves frequent append and pop operations at the list boundaries.

Do note, however, that if you require fast indexed access, a different data structure like a Vec could be more effective.

Next Article: Why LinkedList is rarely used in Rust: performance and use cases

Previous Article: Rust - Circular buffers and rotating elements in VecDeque

Series: Collections in Rust

Rust

You May Also Like

  • E0557 in Rust: Feature Has Been Removed or Is Unavailable in the Stable Channel
  • Network Protocol Handling Concurrency in Rust with async/await
  • Using the anyhow and thiserror Crates for Better Rust Error Tests
  • Rust - Investigating partial moves when pattern matching on vector or HashMap elements
  • Rust - Handling nested or hierarchical HashMaps for complex data relationships
  • Rust - Combining multiple HashMaps by merging keys and values
  • Composing Functionality in Rust Through Multiple Trait Bounds
  • E0437 in Rust: Unexpected `#` in macro invocation or attribute
  • Integrating I/O and Networking in Rust’s Async Concurrency
  • E0178 in Rust: Conflicting implementations of the same trait for a type
  • Utilizing a Reactor Pattern in Rust for Event-Driven Architectures
  • Parallelizing CPU-Intensive Work with Rust’s rayon Crate
  • Managing WebSocket Connections in Rust for Real-Time Apps
  • Downloading Files in Rust via HTTP for CLI Tools
  • Mocking Network Calls in Rust Tests with the surf or reqwest Crates
  • Rust - Designing advanced concurrency abstractions using generic channels or locks
  • Managing code expansion in debug builds with heavy usage of generics in Rust
  • Implementing parse-from-string logic for generic numeric types in Rust
  • Rust.- Refining trait bounds at implementation time for more specialized behavior