Skip to content

Commit c1ad76f

Browse files
committed
Add doubly linked list in Rust
1 parent 62fde88 commit c1ad76f

File tree

2 files changed

+313
-1
lines changed

2 files changed

+313
-1
lines changed

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -2081,7 +2081,7 @@ Com o objetivo de alcançar uma abrangência maior e encorajar mais pessoas a co
20812081
</a>
20822082
</td>
20832083
<td> <!-- Rust -->
2084-
<a href="./CONTRIBUTING.md">
2084+
<a href="./src/rust/doubly_linked_list.rs">
20852085
<img align="center" height="25" src="https://cdn.jsdelivr.net/gh/devicons/devicon/icons/github/github-original.svg" />
20862086
</a>
20872087
</td>

src/rust/doubly_linked_list.rs

+312
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,312 @@
1+
use std::cell::RefCell;
2+
use std::rc::Rc;
3+
4+
pub struct Node<T> {
5+
value: T,
6+
next: Option<Rc<RefCell<Node<T>>>>,
7+
previous: Option<Rc<RefCell<Node<T>>>>,
8+
}
9+
10+
impl<T> Node<T> {
11+
fn new(value: T) -> Self {
12+
Self {
13+
value: value,
14+
next: None,
15+
previous: None,
16+
}
17+
}
18+
}
19+
20+
pub struct DoublyLinkedList<T> {
21+
head: Option<Rc<RefCell<Node<T>>>>,
22+
tail: Option<Rc<RefCell<Node<T>>>>,
23+
}
24+
25+
impl<T> DoublyLinkedList<T> {
26+
pub fn new() -> Self {
27+
DoublyLinkedList {
28+
head: None,
29+
tail: None,
30+
}
31+
}
32+
33+
pub fn add_left(&mut self, value: T) {
34+
let node = Rc::new(RefCell::new(Node::new(value)));
35+
36+
match &self.head {
37+
Some(head_ref) => {
38+
node.borrow_mut().next = Some(head_ref.clone());
39+
head_ref.borrow_mut().previous = Some(node.clone());
40+
self.head = Some(node.clone());
41+
}
42+
None => {
43+
self.head = Some(node.clone());
44+
self.tail = Some(node.clone());
45+
}
46+
}
47+
}
48+
49+
pub fn add_right(&mut self, value: T) {
50+
let node = Rc::new(RefCell::new(Node::new(value)));
51+
52+
match &self.tail {
53+
Some(tail_ref) => {
54+
node.borrow_mut().previous = Some(tail_ref.clone());
55+
tail_ref.borrow_mut().next = Some(node.clone());
56+
self.tail = Some(node.clone());
57+
}
58+
None => {
59+
self.head = Some(node.clone());
60+
self.tail = Some(node.clone());
61+
}
62+
}
63+
}
64+
65+
pub fn remove_left(&mut self) -> Option<T>
66+
where
67+
T: Clone,
68+
{
69+
match &self.head {
70+
Some(head_ref) => {
71+
let value = head_ref.borrow().value.clone();
72+
73+
match &head_ref.clone().borrow().next {
74+
Some(next_ref) => {
75+
next_ref.borrow_mut().previous = None;
76+
self.head = Some(next_ref.clone());
77+
}
78+
None => {
79+
self.head = None;
80+
self.tail = None;
81+
}
82+
}
83+
84+
Some(value)
85+
}
86+
None => None,
87+
}
88+
}
89+
90+
pub fn remove_right(&mut self) -> Option<T>
91+
where
92+
T: Clone,
93+
{
94+
match &self.tail {
95+
Some(tail_ref) => {
96+
let value = tail_ref.borrow().value.clone();
97+
98+
match &tail_ref.clone().borrow().previous {
99+
Some(previous_ref) => {
100+
previous_ref.borrow_mut().next = None;
101+
self.tail = Some(previous_ref.clone());
102+
}
103+
None => {
104+
self.head = None;
105+
self.tail = None;
106+
}
107+
}
108+
109+
Some(value)
110+
}
111+
None => None,
112+
}
113+
}
114+
115+
pub fn peek_left(&self) -> Option<T>
116+
where
117+
T: Clone,
118+
{
119+
match &self.head {
120+
Some(head_ref) => Some(head_ref.borrow().value.clone()),
121+
None => None,
122+
}
123+
}
124+
125+
pub fn peek_right(&self) -> Option<T>
126+
where
127+
T: Clone,
128+
{
129+
match &self.tail {
130+
Some(tail_ref) => Some(tail_ref.borrow().value.clone()),
131+
None => None,
132+
}
133+
}
134+
135+
pub fn remove(&mut self, value: T) -> Option<T>
136+
where
137+
T: Clone + PartialEq,
138+
{
139+
let mut pointer = self.head.clone();
140+
141+
while let Some(node) = pointer {
142+
if node.borrow().value == value {
143+
match &node.borrow().previous {
144+
Some(previous_ref) => match &node.borrow().next {
145+
Some(next_ref) => {
146+
previous_ref.borrow_mut().next = Some(next_ref.clone());
147+
next_ref.borrow_mut().previous = Some(previous_ref.clone());
148+
}
149+
None => {
150+
previous_ref.borrow_mut().next = None;
151+
self.tail = Some(previous_ref.clone());
152+
}
153+
},
154+
None => match &node.borrow().next {
155+
Some(next_ref) => {
156+
next_ref.borrow_mut().previous = None;
157+
self.head = Some(next_ref.clone());
158+
}
159+
None => {
160+
self.head = None;
161+
self.tail = None;
162+
}
163+
},
164+
}
165+
166+
return Some(node.borrow().value.clone());
167+
}
168+
169+
pointer = node.borrow().next.clone();
170+
}
171+
172+
None
173+
}
174+
175+
pub fn find(&self, value: T) -> Option<T>
176+
where
177+
T: Clone + PartialEq,
178+
{
179+
let mut pointer = self.head.clone();
180+
181+
while let Some(node) = pointer {
182+
if node.borrow().value == value {
183+
return Some(node.borrow().value.clone());
184+
}
185+
186+
pointer = node.borrow().next.clone();
187+
}
188+
189+
None
190+
}
191+
192+
pub fn to_vec(&self) -> Vec<T>
193+
where
194+
T: Clone,
195+
{
196+
let mut vec = Vec::new();
197+
198+
let mut pointer = self.head.clone();
199+
200+
while let Some(node) = pointer {
201+
vec.push(node.borrow().value.clone());
202+
pointer = node.borrow().next.clone();
203+
}
204+
205+
vec
206+
}
207+
}
208+
209+
#[cfg(test)]
210+
mod tests {
211+
use super::*;
212+
213+
#[test]
214+
fn test_add_left() {
215+
let mut list = DoublyLinkedList::new();
216+
217+
list.add_left(1);
218+
list.add_left(2);
219+
assert_eq!(list.to_vec(), vec![2, 1]);
220+
}
221+
222+
#[test]
223+
fn test_add_right() {
224+
let mut list = DoublyLinkedList::new();
225+
226+
list.add_right(1);
227+
list.add_right(2);
228+
assert_eq!(list.to_vec(), vec![1, 2]);
229+
}
230+
231+
#[test]
232+
fn test_remove_left() {
233+
let mut list = DoublyLinkedList::new();
234+
235+
list.add_left(1);
236+
list.add_left(2);
237+
238+
assert_eq!(list.remove_left(), Some(2));
239+
assert_eq!(list.remove_left(), Some(1));
240+
assert_eq!(list.remove_left(), None);
241+
}
242+
243+
#[test]
244+
fn test_remove_right() {
245+
let mut list = DoublyLinkedList::new();
246+
247+
list.add_right(1);
248+
list.add_right(2);
249+
250+
assert_eq!(list.remove_right(), Some(2));
251+
assert_eq!(list.remove_right(), Some(1));
252+
assert_eq!(list.remove_right(), None);
253+
}
254+
255+
#[test]
256+
fn test_peek_left() {
257+
let mut list = DoublyLinkedList::new();
258+
259+
list.add_left(1);
260+
list.add_left(2);
261+
262+
assert_eq!(list.peek_left(), Some(2));
263+
assert_eq!(list.peek_left(), Some(2));
264+
}
265+
266+
#[test]
267+
fn test_peek_right() {
268+
let mut list = DoublyLinkedList::new();
269+
270+
list.add_right(1);
271+
list.add_right(2);
272+
273+
assert_eq!(list.peek_right(), Some(2));
274+
assert_eq!(list.peek_right(), Some(2));
275+
}
276+
277+
#[test]
278+
fn test_remove() {
279+
let mut list = DoublyLinkedList::new();
280+
281+
list.add_left(1);
282+
list.add_left(2);
283+
list.add_left(3);
284+
list.add_left(4);
285+
list.add_left(5);
286+
287+
assert_eq!(list.remove(3), Some(3));
288+
assert_eq!(list.remove(1), Some(1));
289+
assert_eq!(list.remove(5), Some(5));
290+
assert_eq!(list.remove(2), Some(2));
291+
assert_eq!(list.remove(6), None);
292+
293+
assert_eq!(list.to_vec(), vec![4]);
294+
}
295+
296+
#[test]
297+
fn test_find() {
298+
let mut list = DoublyLinkedList::new();
299+
300+
list.add_left(1);
301+
list.add_left(2);
302+
list.add_left(3);
303+
list.add_left(4);
304+
list.add_left(5);
305+
306+
assert_eq!(list.find(3), Some(3));
307+
assert_eq!(list.find(1), Some(1));
308+
assert_eq!(list.find(5), Some(5));
309+
assert_eq!(list.find(2), Some(2));
310+
assert_eq!(list.find(6), None);
311+
}
312+
}

0 commit comments

Comments
 (0)