Skip to content

Commit 0b129e8

Browse files
committed
Modified readme file in LinkedList.
1 parent bd7e4b1 commit 0b129e8

File tree

1 file changed

+124
-103
lines changed

1 file changed

+124
-103
lines changed

Linked List/README.markdown

Lines changed: 124 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -110,14 +110,14 @@ Let's also add a property that gives you the last node in the list. This is wher
110110

111111
```swift
112112
public var last: Node? {
113-
if var node = head {
114-
while let next = node.next {
115-
node = next
116-
}
117-
return node
118-
} else {
113+
guard var node = head else {
119114
return nil
120115
}
116+
117+
while let next = node.next {
118+
node = next
119+
}
120+
return node
121121
}
122122
```
123123

@@ -198,16 +198,16 @@ Let's add a method to count how many nodes are in the list. This will look very
198198

199199
```swift
200200
public var count: Int {
201-
if var node = head {
202-
var c = 1
203-
while let next = node.next {
204-
node = next
205-
c += 1
206-
}
207-
return c
208-
} else {
201+
guard var node = head else {
209202
return 0
210203
}
204+
205+
var count = 1
206+
while let next = node.next {
207+
node = next
208+
count += 1
209+
}
210+
return count
211211
}
212212
```
213213

@@ -218,37 +218,43 @@ It loops through the list in the same manner but this time increments a counter
218218
What if we wanted to find the node at a specific index in the list? With an array we can just write `array[index]` and it's an **O(1)** operation. It's a bit more involved with linked lists, but again the code follows a similar pattern:
219219

220220
```swift
221-
public func nodeAt(_ index: Int) -> Node? {
222-
if index >= 0 {
223-
var node = head
224-
var i = index
225-
while node != nil {
226-
if i == 0 { return node }
227-
i -= 1
228-
node = node!.next
221+
public func node(atIndex index: Int) -> Node {
222+
if index == 0 {
223+
return head!
224+
} else {
225+
var node = head!.next
226+
for _ in 1..<index {
227+
node = node?.next
228+
if node == nil { //(*1)
229+
break
230+
}
229231
}
232+
return node!
230233
}
231-
return nil
232234
}
233235
```
234236

235-
The loop looks a little different but it does the same thing: it starts at `head` and then keeps following the `node.next` pointers to step through the list. We're done when we've seen `index` nodes, i.e. when the counter has reached 0.
237+
First we check whether the given index is 0 or not. Because if it is 0, it returns the head as it is.
238+
However, when the given index is greater than 0, it starts at head then keeps following the node.next pointers to step through the list.
239+
The difference from count method at this time is that there are two termination conditions.
240+
One is when the for-loop statement reaches index, and we were able to acquire the node of the given index.
241+
The second is when `node.next` in for-loop statement returns nil and cause break. (*1)
242+
This means that the given index is out of bounds and it causes a crash.
236243

237244
Try it out:
238245

239246
```swift
240247
list.nodeAt(0)!.value // "Hello"
241248
list.nodeAt(1)!.value // "World"
242-
list.nodeAt(2) // nil
249+
// list.nodeAt(2) // crash
243250
```
244251

245252
For fun we can implement a `subscript` method too:
246253

247254
```swift
248255
public subscript(index: Int) -> T {
249-
let node = nodeAt(index)
250-
assert(node != nil)
251-
return node!.value
256+
let node = node(atIndex: index)
257+
return node.value
252258
}
253259
```
254260

@@ -264,84 +270,100 @@ It crashes on `list[2]` because there is no node at that index.
264270

265271
So far we've written code to add new nodes to the end of the list, but that's slow because you need to find the end of the list first. (It would be fast if we used a tail pointer.) For this reason, if the order of the items in the list doesn't matter, you should insert at the front of the list instead. That's always an **O(1)** operation.
266272

267-
Let's write a method that lets you insert a new node at any index in the list. First, we'll define a helper function:
268-
269-
```swift
270-
private func nodesBeforeAndAfter(index: Int) -> (Node?, Node?) {
271-
assert(index >= 0)
272-
273-
var i = index
274-
var next = head
275-
var prev: Node?
276-
277-
while next != nil && i > 0 {
278-
i -= 1
279-
prev = next
280-
next = next!.next
281-
}
282-
assert(i == 0)
283-
284-
return (prev, next)
285-
}
286-
```
287-
288-
This returns a tuple containing the node currently at the specified index and the node that immediately precedes it, if any. The loop is very similar to `nodeAtIndex()`, except that here we also keep track of what the previous node is as we iterate through the list.
289-
290-
Let's look at an example. Suppose we have the following list:
291273

292-
head --> A --> B --> C --> D --> E --> nil
293-
294-
We want to find the nodes before and after index 3. As we start the loop, `i = 3`, `next` points at `"A"`, and `prev` is nil.
295-
296-
head --> A --> B --> C --> D --> E --> nil
297-
next
298-
299-
We decrement `i`, make `prev` point to `"A"`, and move `next` to the next node, `"B"`:
300-
301-
head --> A --> B --> C --> D --> E --> F --> nil
302-
prev next
303-
304-
Again, we decrement `i` and update the pointers. Now `prev` points to `"B"`, and `next` points to `"C"`:
305-
306-
head --> A --> B --> C --> D --> E --> F --> nil
307-
prev next
308-
309-
As you can see, `prev` always follows one behind `next`. We do this one more time and then `i` equals 0 and we exit the loop:
310-
311-
head --> A --> B --> C --> D --> E --> F --> nil
312-
prev next
313-
314-
The `assert()` after the loop checks whether there really were enough nodes in the list. If `i > 0` at this point, then the specified index was too large.
315-
316-
> **Note:** If any of the loops in this article don't make much sense to you, then draw a linked list on a piece of paper and step through the loop by hand, just like what we did here.
317-
318-
For this example, the function returns `("C", "D")` because `"D"` is the node at index 3 and `"C"` is the one right before that.
319-
320-
Now that we have this helper function, we can write the method for inserting nodes:
274+
Let's write a method that lets you insert a new node at any index in the list.
321275

322276
```swift
323-
public func insert(value: T, atIndex index: Int) {
324-
let (prev, next) = nodesBeforeAndAfter(index) // 1
325-
326-
let newNode = Node(value: value) // 2
327-
newNode.previous = prev
328-
newNode.next = next
329-
prev?.next = newNode
330-
next?.previous = newNode
331-
332-
if prev == nil { // 3
333-
head = newNode
334-
}
335-
}
277+
public func insert(_ node: Node, atIndex index: Int) {
278+
let newNode = node
279+
if index == 0 {
280+
newNode.next = head
281+
head?.previous = newNode
282+
head = newNode
283+
} else {
284+
let prev = self.node(atIndex: index-1)
285+
let next = prev.next
286+
287+
newNode.previous = prev
288+
newNode.next = prev.next
289+
prev.next = newNode
290+
next?.previous = newNode
291+
}
292+
}
336293
```
337294

338-
Some remarks about this method:
339-
340-
1. First, we need to find where to insert this node. After calling the helper method, `prev` points to the previous node and `next` is the node currently at the given index. We'll insert the new node in between these two. Note that `prev` can be nil (index is 0), `next` can be nil (index equals size of the list), or both can be nil if the list is empty.
295+
As with node(atIndex :) method, insert(_: at:) method also branches depending on whether the given index is 0 or not.
296+
First let's look at the former case. Suppose we have the following list and the new node(C).
297+
298+
+---------+ +---------+
299+
head --->| |---->| |-----//----->
300+
| A | | B |
301+
nil <---| |<----| |<----//------
302+
+---------+ +---------+
303+
[0] [1]
304+
305+
306+
+---------+
307+
new --->| |----> nil
308+
| C |
309+
| |
310+
+---------+
311+
312+
Now put the new node before the first node. In this way:
313+
314+
new.next = head
315+
head.previous = new
316+
317+
+---------+ +---------+ +---------+
318+
new --->| |--> head -->| |---->| |-----//----->
319+
| C | | A | | B |
320+
| |<-----------| |<----| |<----//------
321+
+---------+ +---------+ +---------+
322+
323+
324+
Finally, replace the head with the new node.
325+
326+
head = new
327+
328+
+---------+ +---------+ +---------+
329+
head --->| |--->| |---->| |-----//----->
330+
| C | | A | | B |
331+
nil <---| |<---| |<----| |<----//------
332+
+---------+ +---------+ +---------+
333+
[0] [1]
334+
335+
336+
However, when the given index is greater than 0, it is necessary to get the node previous and next index and insert between them.
337+
You can also obtain the previous and next node using node(atIndex:) as follows:
338+
339+
+---------+ +---------+ +---------+
340+
head --->| |---//--->| |---->| |----
341+
| 0 | | A | | B |
342+
nil <---| |---//<---| |<----| |<---
343+
+---------+ +---------+ +---------+
344+
[index-1] [index]
345+
^ ^
346+
| |
347+
prev next
348+
349+
prev = node(at: index-1)
350+
next = prev.next
351+
352+
Now insert new node between the prev and the next.
353+
354+
new.prev = prev; prev.next = new // connect prev and new.
355+
new.next = next; next.prev = new // connect new and next.
356+
357+
+---------+ +---------+ +---------+ +---------+
358+
head --->| |---//--->| |---->| |---->| |
359+
| 0 | | A | | C | | B |
360+
nil <---| |---//<---| |<----| |<----| |
361+
+---------+ +---------+ +---------+ +---------+
362+
[index-1] [index] [index+1]
363+
^ ^ ^
364+
| | |
365+
prev new next
341366

342-
2. Create the new node and connect the `previous` and `next` pointers. Because the local `prev` and `next` variables are optionals and may be nil, so we use optional chaining here.
343-
344-
3. If the new node is being inserted at the front of the list, we need to update the `head` pointer. (Note: If the list had a tail pointer, you'd also need to update that pointer here if `next == nil`, because that means the last element has changed.)
345367

346368
Try it out:
347369

@@ -353,8 +375,7 @@ list[2] // "World"
353375
```
354376

355377
Also try adding new nodes to the front and back of the list, to verify that this works properly.
356-
357-
> **Note:** The `nodesBeforeAndAfter()` and `insert(atIndex)` functions can also be used with a singly linked list because we don't depend on the node's `previous` pointer to find the previous element.
378+
> **Note:** The `node(atIndex:)` and `insert(_: atIndex:)` functions can also be used with a singly linked list because we don't depend on the node's `previous` pointer to find the previous element.
358379
359380
What else do we need? Removing nodes, of course! First we'll do `removeAll()`, which is really simple:
360381

@@ -515,7 +536,7 @@ And here's filter:
515536
And a silly example:
516537

517538
```swift
518-
let f = list.filter { s in s.characters.count > 5 }
539+
let f = list.filter { s in s.count > 5 }
519540
f // [Universe, Swifty]
520541
```
521542

0 commit comments

Comments
 (0)