Skip to content

Commit 9008112

Browse files
committed
Updated LinkedList.swift for Swift 3
1 parent 8d03fea commit 9008112

File tree

2 files changed

+201
-10
lines changed

2 files changed

+201
-10
lines changed
Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
/*
2+
Doubly-linked list
3+
4+
Most operations on the linked list have complexity O(n).
5+
*/
6+
public class LinkedListNode<T> {
7+
var value: T
8+
var next: LinkedListNode?
9+
weak var previous: LinkedListNode?
10+
11+
public init(value: T) {
12+
self.value = value
13+
}
14+
}
15+
16+
public class LinkedList<T> {
17+
public typealias Node = LinkedListNode<T>
18+
19+
private var head: Node?
20+
21+
public var isEmpty: Bool {
22+
return head == nil
23+
}
24+
25+
public var first: Node? {
26+
return head
27+
}
28+
29+
public var last: Node? {
30+
if var node = head {
31+
while case let next? = node.next {
32+
node = next
33+
}
34+
return node
35+
} else {
36+
return nil
37+
}
38+
}
39+
40+
public var count: Int {
41+
if var node = head {
42+
var c = 1
43+
while case let next? = node.next {
44+
node = next
45+
c += 1
46+
}
47+
return c
48+
} else {
49+
return 0
50+
}
51+
}
52+
53+
public func nodeAtIndex(index: Int) -> Node? {
54+
if index >= 0 {
55+
var node = head
56+
var i = index
57+
while node != nil {
58+
if i == 0 { return node }
59+
i -= 1
60+
node = node!.next
61+
}
62+
}
63+
return nil
64+
}
65+
66+
public subscript(index: Int) -> T {
67+
let node = nodeAtIndex(index)
68+
assert(node != nil)
69+
return node!.value
70+
}
71+
72+
public func append(value: T) {
73+
let newNode = Node(value: value)
74+
if let lastNode = last {
75+
newNode.previous = lastNode
76+
lastNode.next = newNode
77+
} else {
78+
head = newNode
79+
}
80+
}
81+
82+
private func nodesBeforeAndAfter(index: Int) -> (Node?, Node?) {
83+
assert(index >= 0)
84+
85+
var i = index
86+
var next = head
87+
var prev: Node?
88+
89+
while next != nil && i > 0 {
90+
i -= 1
91+
prev = next
92+
next = next!.next
93+
}
94+
assert(i == 0) // if > 0, then specified index was too large
95+
96+
return (prev, next)
97+
}
98+
99+
public func insert(value: T, atIndex index: Int) {
100+
let (prev, next) = nodesBeforeAndAfter(index)
101+
102+
let newNode = Node(value: value)
103+
newNode.previous = prev
104+
newNode.next = next
105+
prev?.next = newNode
106+
next?.previous = newNode
107+
108+
if prev == nil {
109+
head = newNode
110+
}
111+
}
112+
113+
public func removeAll() {
114+
head = nil
115+
}
116+
117+
public func removeNode(node: Node) -> T {
118+
let prev = node.previous
119+
let next = node.next
120+
121+
if let prev = prev {
122+
prev.next = next
123+
} else {
124+
head = next
125+
}
126+
next?.previous = prev
127+
128+
node.previous = nil
129+
node.next = nil
130+
return node.value
131+
}
132+
133+
public func removeLast() -> T {
134+
assert(!isEmpty)
135+
return removeNode(last!)
136+
}
137+
138+
public func removeAtIndex(index: Int) -> T {
139+
let node = nodeAtIndex(index)
140+
assert(node != nil)
141+
return removeNode(node!)
142+
}
143+
}
144+
145+
extension LinkedList: CustomStringConvertible {
146+
public var description: String {
147+
var s = "["
148+
var node = head
149+
while node != nil {
150+
s += "\(node!.value)"
151+
node = node!.next
152+
if node != nil { s += ", " }
153+
}
154+
return s + "]"
155+
}
156+
}
157+
158+
extension LinkedList {
159+
public func reverse() {
160+
var node = head
161+
while let currentNode = node {
162+
node = currentNode.next
163+
swap(&currentNode.next, &currentNode.previous)
164+
head = currentNode
165+
}
166+
}
167+
}
168+
169+
extension LinkedList {
170+
public func map<U>(transform: T -> U) -> LinkedList<U> {
171+
let result = LinkedList<U>()
172+
var node = head
173+
while node != nil {
174+
result.append(transform(node!.value))
175+
node = node!.next
176+
}
177+
return result
178+
}
179+
180+
public func filter(predicate: T -> Bool) -> LinkedList<T> {
181+
let result = LinkedList<T>()
182+
var node = head
183+
while node != nil {
184+
if predicate(node!.value) {
185+
result.append(node!.value)
186+
}
187+
node = node!.next
188+
}
189+
return result
190+
}
191+
}

Linked List/LinkedList.swift

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public class LinkedListNode<T> {
1616
public class LinkedList<T> {
1717
public typealias Node = LinkedListNode<T>
1818

19-
private var head: Node?
19+
fileprivate var head: Node?
2020

2121
public var isEmpty: Bool {
2222
return head == nil
@@ -64,7 +64,7 @@ public class LinkedList<T> {
6464
}
6565

6666
public subscript(index: Int) -> T {
67-
let node = nodeAtIndex(index)
67+
let node = nodeAtIndex(index: index)
6868
assert(node != nil)
6969
return node!.value
7070
}
@@ -97,7 +97,7 @@ public class LinkedList<T> {
9797
}
9898

9999
public func insert(value: T, atIndex index: Int) {
100-
let (prev, next) = nodesBeforeAndAfter(index)
100+
let (prev, next) = nodesBeforeAndAfter(index: index)
101101

102102
let newNode = Node(value: value)
103103
newNode.previous = prev
@@ -132,13 +132,13 @@ public class LinkedList<T> {
132132

133133
public func removeLast() -> T {
134134
assert(!isEmpty)
135-
return removeNode(last!)
135+
return removeNode(node: last!)
136136
}
137137

138138
public func removeAtIndex(index: Int) -> T {
139-
let node = nodeAtIndex(index)
139+
let node = nodeAtIndex(index: index)
140140
assert(node != nil)
141-
return removeNode(node!)
141+
return removeNode(node: node!)
142142
}
143143
}
144144

@@ -167,22 +167,22 @@ extension LinkedList {
167167
}
168168

169169
extension LinkedList {
170-
public func map<U>(transform: T -> U) -> LinkedList<U> {
170+
public func map<U>(transform: (T)-> U) -> LinkedList<U> {
171171
let result = LinkedList<U>()
172172
var node = head
173173
while node != nil {
174-
result.append(transform(node!.value))
174+
result.append(value: transform(node!.value))
175175
node = node!.next
176176
}
177177
return result
178178
}
179179

180-
public func filter(predicate: T -> Bool) -> LinkedList<T> {
180+
public func filter(predicate: (T)-> Bool) -> LinkedList<T> {
181181
let result = LinkedList<T>()
182182
var node = head
183183
while node != nil {
184184
if predicate(node!.value) {
185-
result.append(node!.value)
185+
result.append(value: node!.value)
186186
}
187187
node = node!.next
188188
}

0 commit comments

Comments
 (0)