refactored
This commit is contained in:
parent
64340ce50a
commit
3790330936
12 changed files with 9 additions and 9 deletions
116
src/data_structures/min_heap.rs
Normal file
116
src/data_structures/min_heap.rs
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
/// A min-heap data structure for managing elements based on their order.
|
||||
///
|
||||
/// This struct implements a min-heap, where the smallest element is always at the top.
|
||||
/// It is generic over type `T`, which must implement the `PartialOrd` trait.
|
||||
pub struct MinHeap<T> {
|
||||
data: Vec<T>,
|
||||
}
|
||||
|
||||
impl<T: PartialOrd> MinHeap<T> {
|
||||
/// Creates a new, empty `MinHeap`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use min_heap::MinHeap;
|
||||
///
|
||||
/// let mut heap: MinHeap<i32> = MinHeap::new();
|
||||
/// ```
|
||||
pub fn new() -> Self {
|
||||
MinHeap { data: Vec::new() }
|
||||
}
|
||||
|
||||
/// Pushes an element onto the heap.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `element` - The element to be pushed onto the heap.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use min_heap::MinHeap;
|
||||
///
|
||||
/// let mut heap: MinHeap<i32> = MinHeap::new();
|
||||
/// heap.push(5);
|
||||
/// heap.push(3);
|
||||
/// ```
|
||||
pub fn push(&mut self, element: T) {
|
||||
self.data.push(element);
|
||||
self.heapify_up(self.data.len() - 1);
|
||||
}
|
||||
|
||||
/// Pops the smallest element from the heap.
|
||||
///
|
||||
/// This removes and returns the smallest element from the heap.
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// The smallest element, if the heap is not empty.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use min_heap::MinHeap;
|
||||
///
|
||||
/// let mut heap: MinHeap<i32> = MinHeap::new();
|
||||
/// heap.push(5);
|
||||
/// heap.push(3);
|
||||
/// assert_eq!(heap.pop(), Some(3));
|
||||
/// ```
|
||||
pub fn pop(&mut self) -> Option<T> {
|
||||
if self.data.is_empty() {
|
||||
return None;
|
||||
}
|
||||
let last_index = self.data.len() - 1;
|
||||
self.data.swap(0, last_index);
|
||||
let result = self.data.pop();
|
||||
self.heapify_down(0);
|
||||
result
|
||||
}
|
||||
|
||||
/// Maintains the heap property by moving an element up.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `index` - The index of the element to be moved up.
|
||||
fn heapify_up(&mut self, mut index: usize) {
|
||||
while index != 0 {
|
||||
let parent_index = (index - 1) / 2;
|
||||
if self.data[index] < self.data[parent_index] {
|
||||
self.data.swap(parent_index, index);
|
||||
}
|
||||
index = parent_index;
|
||||
}
|
||||
}
|
||||
|
||||
/// Maintains the heap property by moving an element down.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `index` - The index of the element to be moved down.
|
||||
fn heapify_down(&mut self, mut index: usize) {
|
||||
let length = self.data.len();
|
||||
loop {
|
||||
let left_child = 2 * index + 1;
|
||||
let right_child = 2 * index + 2;
|
||||
|
||||
let mut smallest = index;
|
||||
|
||||
if left_child < length && self.data[left_child] < self.data[smallest] {
|
||||
smallest = left_child;
|
||||
}
|
||||
|
||||
if right_child < length && self.data[right_child] < self.data[smallest] {
|
||||
smallest = right_child;
|
||||
}
|
||||
|
||||
if smallest != index {
|
||||
self.data.swap(index, smallest);
|
||||
index = smallest;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
5
src/data_structures/mod.rs
Normal file
5
src/data_structures/mod.rs
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
pub mod queue;
|
||||
pub mod stack;
|
||||
pub mod min_heap;
|
||||
pub mod weighted_adj_list;
|
||||
pub mod ring_buffer;
|
||||
24
src/data_structures/queue.rs
Normal file
24
src/data_structures/queue.rs
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
pub struct Queue<T> {
|
||||
queue: Vec<T>,
|
||||
}
|
||||
|
||||
impl<T> Queue<T> {
|
||||
pub fn new() -> Self {
|
||||
Queue { queue: Vec::new() }
|
||||
}
|
||||
pub fn length(&self) -> usize {
|
||||
self.queue.len()
|
||||
}
|
||||
pub fn enqueue(&mut self, item: T) {
|
||||
self.queue.push(item)
|
||||
}
|
||||
pub fn dequeue(&mut self) -> T {
|
||||
self.queue.remove(0)
|
||||
}
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.queue.is_empty()
|
||||
}
|
||||
pub fn peek(&self) -> Option<&T> {
|
||||
self.queue.first()
|
||||
}
|
||||
}
|
||||
111
src/data_structures/ring_buffer.rs
Normal file
111
src/data_structures/ring_buffer.rs
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
#[cfg(test)]
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_push_and_pop() {
|
||||
let mut buffer: RingBuffer<i32> = RingBuffer::new(5);
|
||||
buffer.push(1);
|
||||
buffer.push(2);
|
||||
buffer.push(3);
|
||||
assert_eq!(buffer.pop(), Some(1));
|
||||
assert_eq!(buffer.pop(), Some(2));
|
||||
assert_eq!(buffer.pop(), Some(3));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_peek() {
|
||||
let mut buffer: RingBuffer<i32> = RingBuffer::new(3);
|
||||
buffer.push(10);
|
||||
buffer.push(20);
|
||||
assert_eq!(buffer.peek(), Some(&10));
|
||||
buffer.pop();
|
||||
assert_eq!(buffer.peek(), Some(&20));
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn test_pop_from_empty_buffer() {
|
||||
let mut buffer: RingBuffer<i32> = RingBuffer::new(2);
|
||||
assert_eq!(buffer.pop(), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_buffer_length_and_capacity() {
|
||||
let mut buffer: RingBuffer<i32> = RingBuffer::new(4);
|
||||
buffer.push(1);
|
||||
buffer.push(2);
|
||||
assert_eq!(buffer.len(), 2);
|
||||
assert_eq!(buffer.capacity(), 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_is_empty() {
|
||||
let mut buffer: RingBuffer<i32> = RingBuffer::new(3);
|
||||
assert!(buffer.is_empty());
|
||||
buffer.push(100);
|
||||
assert!(!buffer.is_empty());
|
||||
buffer.pop();
|
||||
assert!(buffer.is_empty());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub struct RingBuffer<T> {
|
||||
buffer: Vec<Option<T>>,
|
||||
capacity: usize,
|
||||
read_pos: usize,
|
||||
write_pos: usize,
|
||||
}
|
||||
|
||||
impl<T> RingBuffer<T> {
|
||||
pub fn new(capacity: usize) -> Self {
|
||||
let mut buffer = Vec::with_capacity(capacity);
|
||||
for _ in 0..capacity {
|
||||
buffer.push(None);
|
||||
}
|
||||
RingBuffer {
|
||||
buffer,
|
||||
capacity,
|
||||
read_pos: 0,
|
||||
write_pos: 0,
|
||||
}
|
||||
}
|
||||
pub fn push(&mut self, item: T) {
|
||||
self.buffer[self.write_pos] = Some(item);
|
||||
if self.len() == self.capacity {
|
||||
self.read_pos = (self.read_pos + 1) % self.capacity; // Move read position if the buffer is full
|
||||
}
|
||||
self.write_pos = (self.write_pos + 1) % self.capacity;
|
||||
}
|
||||
|
||||
pub fn pop(&mut self) -> Option<T> {
|
||||
if self.read_pos == self.write_pos {
|
||||
return None; // Buffer is empty
|
||||
}
|
||||
let item = self.buffer[self.read_pos].take();
|
||||
self.read_pos = (self.read_pos + 1) % self.capacity;
|
||||
item
|
||||
}
|
||||
|
||||
pub fn peek(&self) -> Option<&T> {
|
||||
self.buffer[self.read_pos].as_ref().map(|item| item)
|
||||
}
|
||||
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.read_pos == self.write_pos
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
if self.read_pos <= self.write_pos {
|
||||
self.write_pos - self.read_pos
|
||||
} else {
|
||||
self.capacity - self.read_pos + self.write_pos
|
||||
}
|
||||
}
|
||||
|
||||
pub fn capacity(&self) -> usize {
|
||||
self.capacity
|
||||
}
|
||||
}
|
||||
24
src/data_structures/stack.rs
Normal file
24
src/data_structures/stack.rs
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
pub struct Stack<T> {
|
||||
stack: Vec<T>,
|
||||
}
|
||||
|
||||
impl<T> Stack<T> {
|
||||
pub fn new() -> Self {
|
||||
Stack { stack: Vec::new() }
|
||||
}
|
||||
pub fn length(&self) -> usize {
|
||||
self.stack.len()
|
||||
}
|
||||
pub fn pop(&mut self) -> Option<T> {
|
||||
self.stack.pop()
|
||||
}
|
||||
pub fn push(&mut self, item: T) {
|
||||
self.stack.push(item)
|
||||
}
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.stack.is_empty()
|
||||
}
|
||||
pub fn peek(&self) -> Option<&T> {
|
||||
self.stack.last()
|
||||
}
|
||||
}
|
||||
58
src/data_structures/weighted_adj_list.rs
Normal file
58
src/data_structures/weighted_adj_list.rs
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
pub struct WeightedAdjacencyList<T, W> {
|
||||
vertices: HashMap<T, HashMap<T, W>>,
|
||||
}
|
||||
|
||||
impl<T, W> Clone for WeightedAdjacencyList<T, W>
|
||||
where
|
||||
T: Clone,
|
||||
W: Clone,
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
WeightedAdjacencyList {
|
||||
vertices: self.vertices.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, W> WeightedAdjacencyList<T, W>
|
||||
where
|
||||
T: std::hash::Hash + Eq + Clone,
|
||||
{
|
||||
// Constructor to create a new weighted adjacency list
|
||||
pub fn new() -> Self {
|
||||
WeightedAdjacencyList {
|
||||
vertices: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
// Method to add a vertex to the adjacency list
|
||||
pub fn add_vertex(&mut self, vertex: T) {
|
||||
self.vertices.entry(vertex).or_insert(HashMap::new());
|
||||
}
|
||||
|
||||
// Method to add an edge with weight between two vertices
|
||||
pub fn add_edge(&mut self, from: T, to: T, weight: W) {
|
||||
// Ensure both vertices exist in the adjacency list
|
||||
self.add_vertex(from.clone());
|
||||
self.add_vertex(to.clone());
|
||||
|
||||
// Add the edge from 'from' to 'to' with weight
|
||||
self.vertices.get_mut(&from).unwrap().insert(to, weight);
|
||||
}
|
||||
|
||||
// Method to get the weight of an edge between two vertices
|
||||
pub fn get_weight(&self, from: &T, to: &T) -> Option<&W> {
|
||||
self.vertices.get(from)?.get(to)
|
||||
}
|
||||
|
||||
// Method to get the neighbors of a vertex
|
||||
pub fn get_neighbors(&self, vertex: &T) -> Option<&HashMap<T, W>> {
|
||||
self.vertices.get(vertex)
|
||||
}
|
||||
// Method to get the number of vertices in the adjacency list
|
||||
pub fn len(&self) -> usize {
|
||||
self.vertices.len()
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue