Skip to content

Commit cbdf1ab

Browse files
authored
feat: add the Linked List data structure (alexfertel#36)
1 parent 413c968 commit cbdf1ab

File tree

2 files changed

+287
-0
lines changed

2 files changed

+287
-0
lines changed

src/data_structures/linked_list.rs

+285
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,285 @@
1+
use std::{cell::RefCell, rc::Rc};
2+
3+
type Link<T> = Rc<RefCell<ListNode<T>>>;
4+
5+
fn create_link<T>(val: T) -> Link<T> {
6+
Rc::new(RefCell::new(ListNode::new(val)))
7+
}
8+
9+
#[derive(PartialEq, Debug)]
10+
pub struct ListNode<T> {
11+
pub val: T,
12+
pub next: Option<Link<T>>,
13+
}
14+
15+
impl<T> ListNode<T> {
16+
pub fn new(val: T) -> Self {
17+
Self { next: None, val }
18+
}
19+
}
20+
21+
#[derive(PartialEq, Debug)]
22+
pub struct LinkedList<T> {
23+
head: Option<Link<T>>,
24+
tail: Option<Link<T>>,
25+
length: usize,
26+
}
27+
28+
impl<T> Iterator for LinkedList<T> {
29+
type Item = Link<T>;
30+
31+
fn next(&mut self) -> Option<Self::Item> {
32+
self.pop_front()
33+
}
34+
}
35+
36+
impl<T> LinkedList<T> {
37+
pub fn new() -> Self {
38+
Self {
39+
head: None,
40+
tail: None,
41+
length: 0,
42+
}
43+
}
44+
45+
pub fn len(&self) -> usize {
46+
self.length
47+
}
48+
49+
pub fn push_front(&mut self, val: T) {
50+
let new_head = create_link(val);
51+
match self.head.take() {
52+
Some(link) => {
53+
new_head.borrow_mut().next = Some(link);
54+
self.head = Some(new_head);
55+
}
56+
None => {
57+
self.head = Some(Rc::clone(&new_head));
58+
self.tail = Some(new_head);
59+
}
60+
}
61+
self.length += 1;
62+
}
63+
64+
pub fn push_back(&mut self, val: T) {
65+
let new_tail = create_link(val);
66+
match self.tail.take() {
67+
Some(link) => {
68+
link.borrow_mut().next = Some(Rc::clone(&new_tail));
69+
self.tail = Some(new_tail);
70+
}
71+
None => {
72+
self.head = Some(Rc::clone(&new_tail));
73+
self.tail = Some(new_tail);
74+
}
75+
}
76+
self.length += 1;
77+
}
78+
79+
pub fn push_nth(&mut self, val: T, index: usize) {
80+
let new_link = create_link(val);
81+
match self.peek_nth(index) {
82+
Some(nth) => {
83+
nth.borrow_mut().next = Some(Rc::clone(&new_link));
84+
85+
match nth.borrow_mut().next.take() {
86+
Some(next) => {
87+
new_link.borrow_mut().next = Some(next);
88+
}
89+
None => {
90+
self.tail = Some(Rc::clone(&new_link));
91+
}
92+
}
93+
}
94+
None => {
95+
self.head = Some(Rc::clone(&new_link));
96+
self.tail = Some(new_link);
97+
}
98+
}
99+
self.length += 1;
100+
}
101+
102+
pub fn pop_front(&mut self) -> Option<Link<T>> {
103+
match self.head.take() {
104+
Some(head) => {
105+
self.head = head.borrow_mut().next.take();
106+
self.length -= 1;
107+
Some(head)
108+
}
109+
None => None,
110+
}
111+
}
112+
113+
pub fn pop_back(&mut self) -> Option<Link<T>> {
114+
match self.tail.take() {
115+
Some(tail) => {
116+
let mut new_tail = self.head.take().unwrap();
117+
self.head = Some(Rc::clone(&new_tail));
118+
119+
for _ in 0..self.length {
120+
let temp_ptr = match &new_tail.borrow().next {
121+
Some(val) => match &val.borrow().next {
122+
Some(_) => Some(Rc::clone(&val)),
123+
None => {
124+
break;
125+
}
126+
},
127+
None => {
128+
break;
129+
}
130+
};
131+
new_tail = temp_ptr.unwrap();
132+
}
133+
134+
new_tail.borrow_mut().next = None;
135+
self.tail = Some(new_tail);
136+
self.length -= 1;
137+
Some(tail)
138+
}
139+
None => None,
140+
}
141+
}
142+
143+
pub fn pop_nth(&mut self, index: usize) -> Option<Link<T>> {
144+
if index >= self.len() {
145+
return None;
146+
} else if index == 0 {
147+
return self.pop_front();
148+
} else if index == self.len() - 1 {
149+
return self.pop_back();
150+
}
151+
152+
let nth = self.peek_nth(index);
153+
154+
self.peek_nth(index - 1).unwrap().borrow_mut().next = self.peek_nth(index + 1);
155+
self.length -= 1;
156+
nth
157+
}
158+
159+
pub fn peek_front(&self) -> Option<Link<T>> {
160+
match &self.head {
161+
Some(head) => Some(Rc::clone(head)),
162+
None => None,
163+
}
164+
}
165+
166+
pub fn peek_back(&self) -> Option<Link<T>> {
167+
match &self.tail {
168+
Some(tail) => Some(Rc::clone(tail)),
169+
None => None,
170+
}
171+
}
172+
173+
pub fn peek_nth(&mut self, index: usize) -> Option<Link<T>> {
174+
if index >= self.len() || index == 0 {
175+
return self.peek_front();
176+
} else if index == self.len() - 1 {
177+
return self.peek_back();
178+
}
179+
180+
let mut pointer = self.head.take().unwrap();
181+
self.head = Some(Rc::clone(&pointer));
182+
183+
for _ in 0..index {
184+
let next = pointer.borrow_mut().next.take();
185+
pointer = next.unwrap();
186+
}
187+
188+
Some(pointer)
189+
}
190+
}
191+
192+
#[cfg(test)]
193+
mod test {
194+
use super::{create_link, LinkedList};
195+
196+
fn create_list<T>(arr: &[T]) -> LinkedList<T>
197+
where
198+
T: Clone,
199+
{
200+
let mut list = LinkedList::new();
201+
for num in arr.iter() {
202+
list.push_back((*num).clone());
203+
}
204+
list
205+
}
206+
207+
#[test]
208+
fn push_front_test() {
209+
let mut test_list = create_list(&[1, 2]);
210+
let mut empty_list: LinkedList<i32> = LinkedList::new();
211+
test_list.push_front(0);
212+
empty_list.push_front(0);
213+
assert_eq!(create_list(&[0, 1, 2]), test_list);
214+
assert_eq!(create_list(&[0]), empty_list);
215+
}
216+
217+
#[test]
218+
fn push_back_test() {
219+
let mut test_list = create_list(&[0, 1]);
220+
let mut empty_list: LinkedList<i32> = LinkedList::new();
221+
test_list.push_back(2);
222+
empty_list.push_back(0);
223+
assert_eq!(create_list(&[0, 1, 2]), test_list);
224+
assert_eq!(create_list(&[0]), empty_list);
225+
}
226+
227+
#[test]
228+
fn pop_front_test() {
229+
let mut test_list = create_list(&[0, 1, 2]);
230+
assert_eq!(Some(create_link(0)), test_list.pop_front());
231+
assert_eq!(create_list(&[1, 2]), test_list);
232+
assert_eq!(None, LinkedList::<i32>::new().pop_front());
233+
}
234+
235+
#[test]
236+
fn pop_back_test() {
237+
let mut test_list = create_list(&[0, 1, 2]);
238+
assert_eq!(Some(create_link(2)), test_list.pop_back());
239+
assert_eq!(create_list(&[0, 1]), test_list);
240+
assert_eq!(None, LinkedList::<i32>::new().pop_back());
241+
}
242+
243+
#[test]
244+
fn pop_nth_test() {
245+
let mut test_list = create_list(&[0, 1, 2]);
246+
assert_eq!(create_list(&[1, 2]).peek_front(), test_list.pop_nth(1));
247+
assert_eq!(None, LinkedList::<i32>::new().pop_nth(1));
248+
}
249+
250+
#[test]
251+
fn peek_front_test() {
252+
let test_list = create_list(&[0, 1, 2]);
253+
let link = create_link(0);
254+
255+
link.borrow_mut().next = Some(create_link(1));
256+
link.borrow_mut().next.as_ref().unwrap().borrow_mut().next = Some(create_link(2));
257+
258+
assert_eq!(Some(link), test_list.peek_front());
259+
assert_eq!(None, LinkedList::<i32>::new().peek_front());
260+
}
261+
262+
#[test]
263+
fn peek_back_test() {
264+
let test_list = create_list(&[0, 1, 2]);
265+
assert_eq!(Some(create_link(2)), test_list.peek_back());
266+
assert_eq!(None, LinkedList::<i32>::new().peek_back());
267+
}
268+
269+
#[test]
270+
fn peek_nth_test() {
271+
let mut test_list = create_list(&[0, 1, 2]);
272+
assert_eq!(create_list(&[1, 2]).peek_front(), test_list.peek_nth(1));
273+
assert_eq!(None, LinkedList::<i32>::new().peek_nth(1));
274+
}
275+
276+
#[test]
277+
fn iter_test() {
278+
let arr = &[0, 1, 2];
279+
let test = create_list(arr);
280+
281+
for (i, node) in test.into_iter().enumerate() {
282+
assert_eq!(node.borrow().val, arr[i])
283+
}
284+
}
285+
}

src/data_structures/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
mod heap;
2+
mod linked_list;
23
mod queue;
34
mod stack;
45

56
pub use self::heap::MaxHeap;
67
pub use self::heap::MinHeap;
8+
pub use self::linked_list::LinkedList;
79
pub use self::queue::Queue;
810
pub use self::stack::Stack;

0 commit comments

Comments
 (0)