Skip to content

Commit f20bfa2

Browse files
committed
updated linked list solution desc
1 parent b8fd53a commit f20bfa2

File tree

1 file changed

+30
-24
lines changed

1 file changed

+30
-24
lines changed

rust/doubly-linked-list/Solution.md

Lines changed: 30 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,39 @@
11
# Doubly Linked List
2+
This a very common data struct that you encounter as a developer with a lot of use cases. It is also relatively easy to implement. I implement it in rust for an [exercism](https://exercism.io/) exercise. This article provides a top level walkthrough of the exercise without any implementation details that will spoil the solution, but I do provide a solution at the end.
23

3-
Write a doubly linked list using unsafe Rust, including an iterator over the list
4-
and a cursor for efficient mutation.
5-
6-
The doubly linked list is a fundamental data structure in computer science,
7-
often used in the implementation of other data structures. They're
8-
pervasive in functional programming languages, such as Clojure, Erlang,
9-
or Haskell, but far less common in imperative languages such as Ruby or
10-
Python.
11-
12-
Each node in a doubly linked list contains data and pointers to the next
13-
and previous node, if they exist.
14-
15-
New nodes can be efficiently added at any point in the list, if one already has
16-
a reference to the position. Likewise, all elements
17-
from another list can be inserted at any point in constant time.
18-
19-
In Rust, linked lists are very rarely used, but occasionally they trip up
20-
newcomers, when they try implementing one. Often, they find it unexpectedly
21-
difficult to work with the yet unfamiliar borrow checker.
22-
23-
# Solution
24-
25-
Most of the problem is defining the proper struct to represent each node. For me it looks like this
4+
# Explanation
5+
Most of the problem is defining the proper struct to reference and store your data. The basic block of a `linked list` is a **Node** that stores the data and 2 pointers (previous and next). For me it looks like this
266

277
```rust
288
pub struct Node<T> {
299
pub value: T,
3010
pub previous: *mut Node<T>,
3111
pub next: *mut Node<T>,
3212
}
33-
```
13+
```
14+
15+
Now the `doubly linked list` needs to store a referense to the first and also to the last Node. We access the nodes in the middle by ***walking*** the list from top to bottom and reverse. Here is the struct:
16+
17+
```rust
18+
pub struct LinkedList<T> {
19+
pub head: *mut Node<T>,
20+
pub tail: *mut Node<T>,
21+
size: usize,
22+
}
23+
24+
pub struct Cursor<'a, T> {
25+
list: &'a mut LinkedList<T>,
26+
current: *mut Node<T>,
27+
}
28+
```
29+
30+
A **Cursor**, as the name suggests, points to specific element in the list and allows us to edit the list, add/remove nodes. It is also important to 'point out' that a cursor can change the head or the tail of the list and that's why he needs a mutable reference to it.
31+
32+
# Unsafe
33+
You can clearly see in the code above that I store pointer inside my structs. This is a key difference of this exercise. You **have** to use unsafe in order to dereference this pointer and that is ok. The point of this exercise is to use unsafe code in order to provide a safe API for the users. It is your job to ensure that your code never fails unexpectedly.
34+
35+
# More
36+
Now you are ready to solve this exercise on your own. If you need any more help, I will provide links to resources that can help you and of course my own solution. I suggest you try solving it first.
37+
- [Geeksforgeeks](https://www.geeksforgeeks.org/doubly-linked-list/)
38+
- [Wikipedia](https://en.wikipedia.org/wiki/Doubly_linked_list)
39+
- [My Solution](https://github.com/Dimkar3000/exercism/tree/master/rust/doubly-linked-list)

0 commit comments

Comments
 (0)