Skip to content

Commit 4d244d9

Browse files
committed
linked_list
1 parent 02f2a65 commit 4d244d9

File tree

2 files changed

+90
-10
lines changed

2 files changed

+90
-10
lines changed

homework/src/arc.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ impl<T> Arc<T> {
296296
/// ```
297297
#[inline]
298298
pub fn ptr_eq(this: &Self, other: &Self) -> bool {
299-
this.ptr.as_ptr() == other.ptr.as_ptr()
299+
std::ptr::eq(this.ptr.as_ptr(), other.ptr.as_ptr())
300300
}
301301

302302
/// Returns the inner value, if the given `Arc` is unique.

homework/src/linked_list.rs

Lines changed: 89 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -144,13 +144,38 @@ impl<T> LinkedList<T> {
144144
/// Adds the given node to the back of the list.
145145
#[inline]
146146
fn push_back_node(&mut self, mut node: Node<T>) {
147-
todo!()
147+
node.next = ptr::null_mut();
148+
node.prev = self.tail;
149+
let node = Box::into_raw(Box::new(node));
150+
151+
if self.tail.is_null() {
152+
self.head = node;
153+
} else {
154+
unsafe { (*self.tail).next = node };
155+
}
156+
157+
self.tail = node;
158+
self.len += 1;
148159
}
149160

150161
/// Removes and returns the node at the back of the list.
151162
#[inline]
152163
fn pop_back_node(&mut self) -> Option<Node<T>> {
153-
todo!()
164+
if self.tail.is_null() {
165+
return None;
166+
}
167+
168+
let node = unsafe { Box::from_raw(self.tail) };
169+
self.tail = node.prev;
170+
171+
if self.tail.is_null() {
172+
self.head = ptr::null_mut();
173+
} else {
174+
unsafe { (*self.tail).next = ptr::null_mut() };
175+
}
176+
177+
self.len -= 1;
178+
Some(*node)
154179
}
155180
}
156181

@@ -257,7 +282,20 @@ impl<T> LinkedList<T> {
257282
/// assert!(list1.is_empty());
258283
/// ```
259284
pub fn prepend(&mut self, other: &mut Self) {
260-
todo!()
285+
if self.head.is_null() {
286+
mem::swap(self, other);
287+
return;
288+
}
289+
let other_head = mem::replace(&mut other.head, ptr::null_mut());
290+
if !other_head.is_null() {
291+
unsafe {
292+
(*self.head).prev = other.tail;
293+
(*other.tail).next = self.head;
294+
self.head = other_head;
295+
}
296+
let _ = mem::replace(&mut other.tail, ptr::null_mut());
297+
self.len += mem::replace(&mut other.len, 0);
298+
}
261299
}
262300

263301
/// Provides a forward iterator.
@@ -476,7 +514,7 @@ impl<T> LinkedList<T> {
476514
/// ```
477515
#[inline]
478516
pub fn back(&self) -> Option<&T> {
479-
todo!()
517+
unsafe { self.tail.as_ref() }.map(|node| &node.element)
480518
}
481519

482520
/// Provides a mutable reference to the back element, or `None` if the list
@@ -522,7 +560,7 @@ impl<T> LinkedList<T> {
522560
/// assert_eq!(dl.front().unwrap(), &1);
523561
/// ```
524562
pub fn push_front(&mut self, elt: T) {
525-
todo!()
563+
self.push_front_node(Node::new(elt));
526564
}
527565

528566
/// Removes the first element and returns it, or `None` if the list is
@@ -630,14 +668,30 @@ impl<'a, T> Iterator for IterMut<'a, T> {
630668

631669
#[inline]
632670
fn next(&mut self) -> Option<&'a mut T> {
633-
todo!()
671+
if self.len == 0 {
672+
None
673+
} else {
674+
unsafe { self.head.as_mut() }.map(|node| {
675+
self.len -= 1;
676+
self.head = node.next;
677+
&mut node.element
678+
})
679+
}
634680
}
635681
}
636682

637683
impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
638684
#[inline]
639685
fn next_back(&mut self) -> Option<&'a mut T> {
640-
todo!()
686+
if self.len == 0 {
687+
None
688+
} else {
689+
unsafe { self.tail.as_mut() }.map(|node| {
690+
self.len -= 1;
691+
self.tail = node.prev;
692+
&mut node.element
693+
})
694+
}
641695
}
642696
}
643697

@@ -666,7 +720,29 @@ impl<T> IterMut<'_, T> {
666720
/// ```
667721
#[inline]
668722
pub fn insert_next(&mut self, element: T) {
669-
todo!()
723+
// unsure if this is the correct way to insert an element
724+
let mut node = Node::new(element);
725+
node.next = self.head;
726+
if node.next.is_null() {
727+
node.prev = self.tail;
728+
} else {
729+
node.prev = unsafe { (*self.head).prev };
730+
}
731+
let prev = node.prev;
732+
let next = node.next;
733+
let node_ptr = Box::into_raw(Box::new(node));
734+
if next.is_null() {
735+
self.list.tail = node_ptr;
736+
self.tail = node_ptr;
737+
} else {
738+
unsafe { (*next).prev = node_ptr };
739+
}
740+
if !prev.is_null() {
741+
unsafe { (*prev).next = node_ptr };
742+
} else {
743+
self.list.head = node_ptr;
744+
}
745+
self.list.len += 1;
670746
}
671747

672748
/// Provides a reference to the next element, without changing the iterator.
@@ -686,7 +762,11 @@ impl<T> IterMut<'_, T> {
686762
/// ```
687763
#[inline]
688764
pub fn peek_next(&mut self) -> Option<&mut T> {
689-
todo!()
765+
if !self.head.is_null() {
766+
unsafe { self.head.as_mut() }.map(|node| &mut node.element)
767+
} else {
768+
None
769+
}
690770
}
691771
}
692772

0 commit comments

Comments
 (0)