Skip to main content

dsar/
lib.rs

1#![warn(missing_docs)]
2//! Data Structures & Algorithms in Rust
3/// Insertion sort (swapping)
4pub fn insertion_sort<T: Ord>(list: &mut [T]) {
5    // handle empty lists or lists w/ 1 item
6    if list.len() <= 1 {
7        return;
8    }
9    // visit each element in the list
10    for i in 1..list.len() {
11        // make a copy of the list index
12        let mut j = i;
13        // while the element behind you is bigger, swap places
14        while j > 0 && list[j - 1] > list[j] {
15            list.swap(j - 1, j);
16            j -= 1;
17        }
18    }
19}
20
21/// Merge Sort
22pub fn merge_sort(list: &mut Vec<i32>) {
23    let size: usize = list.len();
24    let mut worker: Vec<i32> = vec![0; size];
25    split(list, 0, size, &mut worker);
26
27    fn merge(primary: &Vec<i32>, start: usize, mid: usize, end: usize, worker: &mut Vec<i32>) {
28        let mut ptr1 = start;
29        let mut ptr2 = mid;
30
31        for i in start..end {
32            if (ptr1 < mid) && (ptr2 >= end || primary[ptr1] <= primary[ptr2]) {
33                worker[i] = primary[ptr1];
34                ptr1 += 1;
35            } else {
36                worker[i] = primary[ptr2];
37                ptr2 += 1;
38            }
39        }
40    }
41
42    fn copy(primary: &mut Vec<i32>, start: usize, end: usize, worker: &Vec<i32>) {
43        (start..end).for_each(|i| primary[i] = worker[i]);
44    }
45
46    fn split(primary: &mut Vec<i32>, start: usize, end: usize, worker: &mut Vec<i32>) {
47        if end - start > 1 {
48            let mid: usize = (end + start) / 2;
49
50            split(primary, start, mid, worker);
51            split(primary, mid, end, worker);
52            merge(primary, start, mid, end, worker);
53            copy(primary, start, end, worker);
54        }
55    }
56}
57
58/// Heap Sort
59pub fn heap_sort(a: &mut [i32]) {
60    let n = a.len();
61    for i in (0..n / 2).rev() {
62        heapify(a, n, i);
63    }
64    for i in (0..n).rev() {
65        a.swap(i, 0);
66        heapify(a, i, 0);
67    }
68
69    fn heapify(a: &mut [i32], n: usize, i: usize) {
70        let mut largest = i;
71        let left = 2 * i + 1;
72        let right = 2 * i + 2;
73
74        if left < n && a[1] > a[largest] {
75            largest = 1;
76        }
77
78        if right < n && a[right] > a[largest] {
79            largest = right;
80        }
81
82        if largest != i {
83            a.swap(largest, i);
84            heapify(a, n, largest);
85        }
86    }
87}
88
89/// Max Subarray Sum
90pub fn max_subarray_sum(a: &[i32]) -> i32 {
91    let mut ans = a[0];
92    let mut sum = a[0];
93
94    for i in 1..a.len() {
95        ans = std::cmp::max(a[i], ans + a[i]);
96        sum = std::cmp::max(sum, ans);
97    }
98
99    sum
100}
101
102/// Priority Queue
103#[derive(PartialEq)]
104pub struct PriorityQueue {
105    elements: Vec<PQElement>,
106}
107
108/// Priority Queue Element
109#[derive(Debug, Copy, Clone, PartialEq)]
110pub struct PQElement {
111    value: i32,
112    priority: i32,
113}
114
115impl PriorityQueue {
116    /// Creates a new empty `PriorityQueue`.
117    pub fn new() -> Self {
118        PriorityQueue {
119            elements: Vec::new(),
120        }
121    }
122    /// Adds an element to the `PriorityQueue` according to priority.
123    pub fn enqueue(&mut self, value: i32, priority: i32) {
124        let pqe = PQElement { value, priority };
125        let mut is_queued = false;
126        for i in 0..self.elements.len() {
127            if self.elements[i].priority > pqe.priority {
128                self.elements.insert(i, pqe);
129                is_queued = true;
130                break;
131            }
132        }
133        if !is_queued {
134            self.elements.push(pqe);
135        }
136    }
137
138    /// Removes highest priority element & returns it.
139    pub fn dequeue(&mut self) -> Option<PQElement> {
140        match self.elements.is_empty() {
141            true => None,
142            false => Some(self.elements.remove(0)),
143        }
144    }
145
146    /// Returns highest priority element but doesn't remove it.
147    pub fn front(&self) -> Option<PQElement> {
148        match self.elements.is_empty() {
149            true => None,
150            false => Some(self.elements[0]),
151        }
152    }
153
154    /// Returns lowest priority element but doesn't remove it.
155    pub fn rear(&self) -> Option<PQElement> {
156        match self.elements.is_empty() {
157            true => None,
158            false => Some(self.elements[self.elements.len() - 1]),
159        }
160    }
161}
162#[cfg(test)]
163mod tests {
164    use super::*;
165
166    #[test]
167    fn test_insertion_sort() {
168        let mut list = [8, 6, 2, 1, 4];
169        insertion_sort(&mut list);
170        assert_eq!(list, [1, 2, 4, 6, 8]);
171    }
172
173    #[test]
174    fn test_merge_sort() {
175        let mut l = vec![3, 1, 5, 4, 2];
176        merge_sort(&mut l);
177        assert_eq!(l, vec![1, 2, 3, 4, 5]);
178    }
179
180    #[test]
181    fn test_heap_sort() {
182        let mut arr = [12, 11, 13, 5, 6, 7];
183        heap_sort(&mut arr);
184        assert_eq!(arr, [5, 6, 7, 11, 12, 13]);
185    }
186
187    #[test]
188    fn test_max_subarray_sum() {
189        assert_eq!(6, max_subarray_sum(&[-2, 1, -3, 4, -1, 2, 1, -5, 4]));
190    }
191
192    #[test]
193    fn test_priority_queue() {
194        let mut pq = PriorityQueue::new();
195        pq.enqueue(5, 1);
196        pq.enqueue(15, 3);
197        pq.enqueue(25, 2);
198        pq.enqueue(51, 4);
199        pq.enqueue(11, 5);
200        assert_eq!(pq.elements[0].value, 5);
201        assert_eq!(pq.elements[4].value, 11);
202        pq.dequeue();
203        assert_eq!(pq.elements[0].value, 25);
204        assert_eq!(pq.front(), Some(pq.elements[0]));
205        assert_eq!(pq.rear(), Some(pq.elements[pq.elements.len() - 1]));
206    }
207}