@@ -42,54 +42,58 @@ public final class LinkedList<T> {
42
42
43
43
/// Computed property to iterate through the linked list and return the last node in the list (if any)
44
44
public var last : Node ? {
45
- if var node = head {
46
- while case let next? = node. next {
47
- node = next
48
- }
49
- return node
50
- } else {
45
+ guard let head = head else {
51
46
return nil
52
47
}
48
+ var node = head
49
+ while let next = node. next {
50
+ node = next
51
+ }
52
+ return node
53
53
}
54
54
55
55
/// Computed property to iterate through the linked list and return the total number of nodes
56
56
public var count : Int {
57
- if var node = head {
58
- var c = 1
59
- while case let next? = node. next {
60
- node = next
61
- c += 1
62
- }
63
- return c
64
- } else {
57
+ guard let head = head else {
65
58
return 0
66
59
}
60
+ var node = head
61
+ var count = 1
62
+ while let next = node. next {
63
+ node = next
64
+ count += 1
65
+ }
66
+ return count
67
67
}
68
68
69
69
/// Function to return the node at a specific index. Crashes if index is out of bounds (0...self.count)
70
70
///
71
71
/// - Parameter index: Integer value of the node's index to be returned
72
72
/// - Returns: Optional LinkedListNode
73
- public func node( atIndex index: Int ) -> Node ? {
74
- if index >= 0 {
75
- var node = head
76
- var i = index
77
- while node != nil {
78
- if i == 0 { return node }
79
- i -= 1
80
- node = node!. next
81
- }
73
+ public func node( atIndex index: Int ) -> Node {
74
+ assert ( head != nil , " List is empty " )
75
+ if index == 0 {
76
+ return head!
77
+ } else {
78
+ var node = head!. next
79
+ for _ in 1 ..< index {
80
+ node = node? . next
81
+ if node == nil {
82
+ break
83
+ }
84
+ }
85
+
86
+ assert ( node != nil , " index is out of bounds. " )
87
+ return node!
82
88
}
83
- return nil
84
89
}
85
90
86
91
/// Subscript function to return the node at a specific index
87
92
///
88
93
/// - Parameter index: Integer value of the requested value's index
89
94
public subscript( index: Int ) -> T {
90
95
let node = self . node ( atIndex: index)
91
- assert ( node != nil )
92
- return node!. value
96
+ return node. value
93
97
}
94
98
95
99
/// Append a value to the end of the list
@@ -104,7 +108,7 @@ public final class LinkedList<T> {
104
108
///
105
109
/// - Parameter node: The node containing the value to be appended
106
110
public func append( _ node: Node ) {
107
- let newNode = LinkedListNode ( value : node. value )
111
+ let newNode = node
108
112
if let lastNode = last {
109
113
newNode. previous = lastNode
110
114
lastNode. next = newNode
@@ -124,27 +128,6 @@ public final class LinkedList<T> {
124
128
}
125
129
}
126
130
127
- /// A private helper funciton to find the nodes before and after a specified index. Crashes if index is out of bounds (0...self.count)
128
- ///
129
- /// - Parameter index: Integer value of the index between the nodes.
130
- /// - Returns: A tuple of 2 nodes before & after the specified index respectively.
131
- private func nodesBeforeAndAfter( index: Int ) -> ( Node ? , Node ? ) {
132
- assert ( index >= 0 )
133
-
134
- var i = index
135
- var next = head
136
- var prev : Node ?
137
-
138
- while next != nil && i > 0 {
139
- i -= 1
140
- prev = next
141
- next = next!. next
142
- }
143
- assert ( i == 0 ) // if > 0, then specified index was too large
144
-
145
- return ( prev, next)
146
- }
147
-
148
131
/// Insert a value at a specific index. Crashes if index is out of bounds (0...self.count)
149
132
///
150
133
/// - Parameters:
@@ -161,41 +144,42 @@ public final class LinkedList<T> {
161
144
/// - node: The node containing the value to be inserted
162
145
/// - index: Integer value of the index to be inserted at
163
146
public func insert( _ node: Node , atIndex index: Int ) {
164
- let ( prev, next) = nodesBeforeAndAfter ( index: index)
165
147
let newNode = LinkedListNode ( value: node. value)
166
- newNode. previous = prev
167
- newNode. next = next
168
- prev? . next = newNode
169
- next? . previous = newNode
170
-
171
- if prev == nil {
148
+ if index == 0 {
149
+ newNode. next = head
150
+ head? . previous = newNode
172
151
head = newNode
152
+ } else {
153
+ let separator = self . node ( atIndex: index- 1 )
154
+ newNode. previous = separator
155
+ newNode. next = separator. next
156
+ separator. next? . previous = newNode
157
+ separator. next = newNode
173
158
}
174
159
}
175
-
160
+
176
161
/// Insert a copy of a LinkedList at a specific index. Crashes if index is out of bounds (0...self.count)
177
162
///
178
163
/// - Parameters:
179
164
/// - list: The LinkedList to be copied and inserted
180
165
/// - index: Integer value of the index to be inserted at
181
166
public func insert( _ list: LinkedList , atIndex index: Int ) {
182
167
if list. isEmpty { return }
183
- var ( prev, next) = nodesBeforeAndAfter ( index: index)
184
- var nodeToCopy = list. head
185
- var newNode : Node ?
186
- while let node = nodeToCopy {
187
- newNode = Node ( value: node. value)
188
- newNode? . previous = prev
189
- if let previous = prev {
190
- previous. next = newNode
191
- } else {
192
- self . head = newNode
193
- }
194
- nodeToCopy = nodeToCopy? . next
195
- prev = newNode
168
+
169
+ if index == 0 {
170
+ let temp = head
171
+ head = list. head
172
+ list. last? . next = temp
173
+ } else {
174
+ let separate = self . node ( atIndex: index- 1 )
175
+ let temp = separate. next
176
+
177
+ separate. next = list. head
178
+ list. head? . previous = separate
179
+
180
+ list. last? . next = temp
181
+ temp? . previous = list. last? . next
196
182
}
197
- prev? . next = next
198
- next? . previous = prev
199
183
}
200
184
201
185
/// Function to remove all nodes/value from the list
@@ -237,8 +221,7 @@ public final class LinkedList<T> {
237
221
/// - Returns: The data value contained in the deleted node
238
222
@discardableResult public func remove( atIndex index: Int ) -> T {
239
223
let node = self . node ( atIndex: index)
240
- assert ( node != nil )
241
- return remove ( node: node!)
224
+ return remove ( node: node)
242
225
}
243
226
}
244
227
@@ -324,7 +307,7 @@ list.first // nil
324
307
list. last // nil
325
308
326
309
list. append ( " Hello " )
327
- list. isEmpty
310
+ list. isEmpty // false
328
311
list. first!. value // "Hello"
329
312
list. last!. value // "Hello"
330
313
list. count // 1
@@ -339,9 +322,9 @@ list.first!.next!.value // "World"
339
322
list. last!. previous!. value // "Hello"
340
323
list. last!. next // nil
341
324
342
- list. node ( atIndex: 0 ) ! . value // "Hello"
343
- list. node ( atIndex: 1 ) ! . value // "World"
344
- list. node ( atIndex: 2 ) // nil
325
+ list. node ( atIndex: 0 ) . value // "Hello"
326
+ list. node ( atIndex: 1 ) . value // "World"
327
+ // list.node(atIndex: 2) // crash!
345
328
346
329
list [ 0 ] // "Hello"
347
330
list [ 1 ] // "World"
@@ -364,25 +347,49 @@ print(list)
364
347
365
348
list. reverse ( ) // [World, Swift, Hello]
366
349
367
- list. node ( atIndex: 0 ) ! . value = " Universe "
368
- list. node ( atIndex: 1 ) ! . value = " Swifty "
369
- let m = list. map { s in s. characters . count }
350
+ list. node ( atIndex: 0 ) . value = " Universe "
351
+ list. node ( atIndex: 1 ) . value = " Swifty "
352
+ let m = list. map { s in s. count }
370
353
m // [8, 6, 5]
371
- let f = list. filter { s in s. characters . count > 5 }
354
+ let f = list. filter { s in s. count > 5 }
372
355
f // [Universe, Swifty]
373
356
374
357
list. remove ( node: list. first!) // "Universe"
375
358
list. count // 2
376
359
list [ 0 ] // "Swifty"
377
360
list [ 1 ] // "Hello"
378
361
362
+ list. count // 2
379
363
list. removeLast ( ) // "Hello"
364
+ list. head? . value
380
365
list. count // 1
381
366
list [ 0 ] // "Swifty"
382
367
383
368
list. remove ( atIndex: 0 ) // "Swifty"
384
369
list. count // 0
385
370
371
+ let list3 = LinkedList < String > ( )
372
+ list3. insert ( " 2 " , atIndex: 0 ) // [2]
373
+ list3. count // 1
374
+ list3. insert ( " 4 " , atIndex: 1 ) // [2,4]
375
+ list3. count // 2
376
+ list3. insert ( " 5 " , atIndex: 2 ) // [2,4,5]
377
+ list3. count // 3
378
+ list3. insert ( " 3 " , atIndex: 1 ) // [2,3,4,5]
379
+ list3. insert ( " 1 " , atIndex: 0 ) // [1,2,3,4,5]
380
+
381
+ let list4 = LinkedList < String > ( )
382
+ list4. insert ( list3, atIndex: 0 ) // [1,2,3,4,5]
383
+ list4. count // 5
384
+
385
+ let list5 = LinkedList < String > ( )
386
+ list5. append ( " 0 " ) // [0]
387
+ list5. insert ( " End " , atIndex: 1 ) // [0,End]
388
+ list5. count // 2
389
+ list5. insert ( list4, atIndex: 1 ) // [0,1,2,3,4,5,End]
390
+ list5. count // 7
391
+
392
+
386
393
let linkedList : LinkedList < Int > = [ 1 , 2 , 3 , 4 ] // [1, 2, 3, 4]
387
394
linkedList. count // 4
388
395
linkedList [ 0 ] // 1
0 commit comments