Skip to content

Commit fcd1535

Browse files
Add explanation
1 parent 42b12e8 commit fcd1535

File tree

1 file changed

+128
-0
lines changed

1 file changed

+128
-0
lines changed

SinglyLinkedList/README.md

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
# Singly Linked List
2+
3+
Singly linked lists are basic data structures that enable linking of related elements. Linked lists are not unlike arrays. They provide insertion, retrieval, updating, and removal of their elements. The elements of a linked list are referred to as 'nodes.' Each node has two properties: a value, and pointer the the next node in the list.They provide O(n) time for storage and lookup. See below for the memory implications and differences between singly and doubly linked lists.
4+
5+
### Linked List vs. Array
6+
7+
One major difference between linked lists and arrays are that the elements of a linked list are not stored 'contiguously' in memory as in an array. This means that elements can be inserted or removed without having to reorganize their entire structure. Conversely, linked lists do not random access to the data or efficient indexing of their elements.
8+
9+
#### Singly linked list vs. Doubly linked list
10+
A singly linked list's nodes contain only their key (or data) and a pointer to the next node in the list. A Doubly linked list contains nodes that have a key, a pointer to the next node, and also a pointer to the previous node in the list.
11+
Doubly linked lists require more memory per node, but can provide easier manipulation than singly linked lists.
12+
13+
In Swift, you might write a simple data structure to represent a node that holds nintegers like this:
14+
15+
```swift
16+
class Node {
17+
var key: Int
18+
var next: Node?
19+
}
20+
```
21+
Note the type of the 'next' property. If we are at the end of our list or if our list is empty, there is no next link. Because of this, 'next' is of type optional node. What if we want a linked list of something other than integers, or support nil-values for keys? We can make our data structure generic.
22+
23+
```swift
24+
class Node<T> {
25+
var key: T?
26+
var next: Node<T>?
27+
}
28+
```
29+
30+
#### Head and Tail
31+
A linked list's first node is referred to as its 'head'. The term 'tail' can be used to refer to the last node in the list, or to all the nodes in the list after the head.
32+
33+
To create a linked list of nodes, we create a class with a generic type. Because we'll need to compare the nodes on the basis of equality, we constrain our generic type 'T' to conform to Swift's Equatable protocol.
34+
35+
Here is one implementation of a singly linked list in Swift:
36+
37+
```swift
38+
class SinglyLinkedList<T: Equatable> {
39+
var head = Node<T>()
40+
}
41+
```
42+
To support insertion of nodes to the list, we write a function that takes a key of type 'T'.
43+
44+
```swift
45+
func addLink(key: T) {
46+
47+
/* Check if the head's key is nil, and if so,
48+
assign it the value of the parameter passed in */
49+
50+
guard head.key != nil else { return head.key = key }
51+
52+
//create local variable and initialize it with the head
53+
var current: Node? = head
54+
55+
/* Begin while loop that finds the last node in the list and creates
56+
a new node with the value of the parameter at the end of the list */
57+
FindEmptySpot: while current != nil {
58+
if current?.next == nil {
59+
current?.next = Node<T>(key: key)
60+
break FindEmptySpot
61+
} else {
62+
current = current?.next
63+
}
64+
}
65+
}
66+
```
67+
Before we can write a function that removes a node by its index, we'll need to know the count of nodes in our list. We'll also include a computed property that will tell us if a list is empty.
68+
69+
```swift
70+
var count: Int {
71+
guard head.key != nil else { return 0 }
72+
var current = head
73+
var x = 1
74+
while let next = current.next {
75+
current = next
76+
x += 1
77+
}
78+
return x
79+
}
80+
81+
var isEmpty: Bool {
82+
return head.key == nil
83+
}
84+
```
85+
86+
87+
To support deletion of nodes in the list, we write a function that accepts the index of the node to remove. We'll have to reorganize the nodes that surround the link that is removed.
88+
89+
```swift
90+
func removeLinkAtIndex(index: Int) {
91+
/* Verify that the index passed as an argument to the function
92+
is >= the index of the head and <= the last node in the list.
93+
If the list is empty, we'll simply return. */
94+
95+
guard index >= 0 && index <= self.count - 1 && head.key != nil else { return }
96+
97+
98+
/* Create local variables for the current node,
99+
the trailing node, and an index */
100+
the current node with the head node */
101+
102+
var current: Node<T>? = head
103+
var trailer: Node<T>?
104+
var listIndex = 0
105+
106+
/* If the link to be removed is the head */
107+
if index == 0 {
108+
current = current?.next
109+
head = current?.next ?? Node<T>()
110+
return
111+
}
112+
113+
/* Begin while loop that shuffles through the nodes in the list.
114+
When the index of the node to be removed is reached, we assign
115+
the node a nil value, and break out of the loop */
116+
while current != nil {
117+
if listIndex == index {
118+
trailer?.next = current?.next
119+
current = nil
120+
break
121+
}
122+
trailer = current
123+
current = current?.next
124+
listIndex += 1
125+
}
126+
}
127+
```
128+
Linked lists are relatively simple structures, but can be used to implement other common data types like stacks and queues. It can be helpful to better understand how they differ from the Array type and what memory and efficiency implications are associated with their use.

0 commit comments

Comments
 (0)