Skip to content

Commit d54ad28

Browse files
authored
Merge pull request kodecocodes#311 from nerdo/master
+ methods to append, insert, remove node objects
2 parents b9b491d + 4072983 commit d54ad28

File tree

1 file changed

+187
-179
lines changed

1 file changed

+187
-179
lines changed

Linked List/LinkedList.swift

+187-179
Original file line numberDiff line numberDiff line change
@@ -1,198 +1,206 @@
11
public class LinkedListNode<T> {
2-
var value: T
3-
var next: LinkedListNode?
4-
weak var previous: LinkedListNode?
5-
6-
public init(value: T) {
7-
self.value = value
8-
}
2+
var value: T
3+
var next: LinkedListNode?
4+
weak var previous: LinkedListNode?
5+
6+
public init(value: T) {
7+
self.value = value
8+
}
99
}
1010

1111
public class LinkedList<T> {
12-
public typealias Node = LinkedListNode<T>
13-
14-
fileprivate var head: Node?
15-
16-
public init() {}
17-
18-
public var isEmpty: Bool {
19-
return head == nil
20-
}
21-
22-
public var first: Node? {
23-
return head
24-
}
25-
26-
public var last: Node? {
27-
if var node = head {
28-
while case let next? = node.next {
29-
node = next
30-
}
31-
return node
32-
} else {
33-
return nil
34-
}
35-
}
36-
37-
public var count: Int {
38-
if var node = head {
39-
var c = 1
40-
while case let next? = node.next {
41-
node = next
42-
c += 1
43-
}
44-
return c
45-
} else {
46-
return 0
47-
}
48-
}
49-
50-
public func node(atIndex index: Int) -> Node? {
51-
if index >= 0 {
52-
var node = head
53-
var i = index
54-
while node != nil {
55-
if i == 0 { return node }
56-
i -= 1
57-
node = node!.next
58-
}
59-
}
60-
return nil
61-
}
62-
63-
public subscript(index: Int) -> T {
64-
let node = self.node(atIndex: index)
65-
assert(node != nil)
66-
return node!.value
67-
}
68-
69-
public func append(_ value: T) {
70-
let newNode = Node(value: value)
71-
if let lastNode = last {
72-
newNode.previous = lastNode
73-
lastNode.next = newNode
74-
} else {
75-
head = newNode
76-
}
77-
}
78-
79-
private func nodesBeforeAndAfter(index: Int) -> (Node?, Node?) {
80-
assert(index >= 0)
81-
82-
var i = index
83-
var next = head
84-
var prev: Node?
85-
86-
while next != nil && i > 0 {
87-
i -= 1
88-
prev = next
89-
next = next!.next
90-
}
91-
assert(i == 0) // if > 0, then specified index was too large
92-
93-
return (prev, next)
94-
}
95-
96-
public func insert(_ value: T, atIndex index: Int) {
97-
let (prev, next) = nodesBeforeAndAfter(index: index)
98-
99-
let newNode = Node(value: value)
100-
newNode.previous = prev
101-
newNode.next = next
102-
prev?.next = newNode
103-
next?.previous = newNode
104-
105-
if prev == nil {
106-
head = newNode
107-
}
108-
}
109-
110-
public func removeAll() {
111-
head = nil
112-
}
113-
114-
public func remove(node: Node) -> T {
115-
let prev = node.previous
116-
let next = node.next
117-
118-
if let prev = prev {
119-
prev.next = next
120-
} else {
121-
head = next
122-
}
123-
next?.previous = prev
124-
125-
node.previous = nil
126-
node.next = nil
127-
return node.value
128-
}
129-
130-
public func removeLast() -> T {
131-
assert(!isEmpty)
132-
return remove(node: last!)
133-
}
134-
135-
public func remove(atIndex index: Int) -> T {
136-
let node = self.node(atIndex: index)
137-
assert(node != nil)
138-
return remove(node: node!)
139-
}
12+
public typealias Node = LinkedListNode<T>
13+
14+
fileprivate var head: Node?
15+
16+
public init() {}
17+
18+
public var isEmpty: Bool {
19+
return head == nil
20+
}
21+
22+
public var first: Node? {
23+
return head
24+
}
25+
26+
public var last: Node? {
27+
if var node = head {
28+
while case let next? = node.next {
29+
node = next
30+
}
31+
return node
32+
} else {
33+
return nil
34+
}
35+
}
36+
37+
public var count: Int {
38+
if var node = head {
39+
var c = 1
40+
while case let next? = node.next {
41+
node = next
42+
c += 1
43+
}
44+
return c
45+
} else {
46+
return 0
47+
}
48+
}
49+
50+
public func node(atIndex index: Int) -> Node? {
51+
if index >= 0 {
52+
var node = head
53+
var i = index
54+
while node != nil {
55+
if i == 0 { return node }
56+
i -= 1
57+
node = node!.next
58+
}
59+
}
60+
return nil
61+
}
62+
63+
public subscript(index: Int) -> T {
64+
let node = self.node(atIndex: index)
65+
assert(node != nil)
66+
return node!.value
67+
}
68+
69+
public func append(_ value: T) {
70+
let newNode = Node(value: value)
71+
self.append(newNode)
72+
}
73+
74+
public func append(_ newNode: Node) {
75+
if let lastNode = last {
76+
newNode.previous = lastNode
77+
lastNode.next = newNode
78+
} else {
79+
head = newNode
80+
}
81+
}
82+
83+
private func nodesBeforeAndAfter(index: Int) -> (Node?, Node?) {
84+
assert(index >= 0)
85+
86+
var i = index
87+
var next = head
88+
var prev: Node?
89+
90+
while next != nil && i > 0 {
91+
i -= 1
92+
prev = next
93+
next = next!.next
94+
}
95+
assert(i == 0) // if > 0, then specified index was too large
96+
97+
return (prev, next)
98+
}
99+
100+
public func insert(_ value: T, atIndex index: Int) {
101+
let newNode = Node(value: value)
102+
self.insert(newNode, atIndex: index)
103+
}
104+
105+
public func insert(_ newNode: Node, atIndex index: Int) {
106+
let (prev, next) = nodesBeforeAndAfter(index: index)
107+
108+
newNode.previous = prev
109+
newNode.next = next
110+
prev?.next = newNode
111+
next?.previous = newNode
112+
113+
if prev == nil {
114+
head = newNode
115+
}
116+
}
117+
118+
public func removeAll() {
119+
head = nil
120+
}
121+
122+
@discardableResult public func remove(node: Node) -> T {
123+
let prev = node.previous
124+
let next = node.next
125+
126+
if let prev = prev {
127+
prev.next = next
128+
} else {
129+
head = next
130+
}
131+
next?.previous = prev
132+
133+
node.previous = nil
134+
node.next = nil
135+
return node.value
136+
}
137+
138+
@discardableResult public func removeLast() -> T {
139+
assert(!isEmpty)
140+
return remove(node: last!)
141+
}
142+
143+
@discardableResult public func remove(atIndex index: Int) -> T {
144+
let node = self.node(atIndex: index)
145+
assert(node != nil)
146+
return remove(node: node!)
147+
}
140148
}
141149

142150
extension LinkedList: CustomStringConvertible {
143-
public var description: String {
144-
var s = "["
145-
var node = head
146-
while node != nil {
147-
s += "\(node!.value)"
148-
node = node!.next
149-
if node != nil { s += ", " }
150-
}
151-
return s + "]"
152-
}
151+
public var description: String {
152+
var s = "["
153+
var node = head
154+
while node != nil {
155+
s += "\(node!.value)"
156+
node = node!.next
157+
if node != nil { s += ", " }
158+
}
159+
return s + "]"
160+
}
153161
}
154162

155163
extension LinkedList {
156-
public func reverse() {
157-
var node = head
158-
while let currentNode = node {
159-
node = currentNode.next
160-
swap(&currentNode.next, &currentNode.previous)
161-
head = currentNode
162-
}
163-
}
164+
public func reverse() {
165+
var node = head
166+
while let currentNode = node {
167+
node = currentNode.next
168+
swap(&currentNode.next, &currentNode.previous)
169+
head = currentNode
170+
}
171+
}
164172
}
165173

166174
extension LinkedList {
167-
public func map<U>(transform: (T) -> U) -> LinkedList<U> {
168-
let result = LinkedList<U>()
169-
var node = head
170-
while node != nil {
171-
result.append(transform(node!.value))
172-
node = node!.next
173-
}
174-
return result
175-
}
176-
177-
public func filter(predicate: (T) -> Bool) -> LinkedList<T> {
178-
let result = LinkedList<T>()
179-
var node = head
180-
while node != nil {
181-
if predicate(node!.value) {
182-
result.append(node!.value)
183-
}
184-
node = node!.next
185-
}
186-
return result
187-
}
175+
public func map<U>(transform: (T) -> U) -> LinkedList<U> {
176+
let result = LinkedList<U>()
177+
var node = head
178+
while node != nil {
179+
result.append(transform(node!.value))
180+
node = node!.next
181+
}
182+
return result
183+
}
184+
185+
public func filter(predicate: (T) -> Bool) -> LinkedList<T> {
186+
let result = LinkedList<T>()
187+
var node = head
188+
while node != nil {
189+
if predicate(node!.value) {
190+
result.append(node!.value)
191+
}
192+
node = node!.next
193+
}
194+
return result
195+
}
188196
}
189197

190198
extension LinkedList {
191-
convenience init(array: Array<T>) {
192-
self.init()
199+
convenience init(array: Array<T>) {
200+
self.init()
193201

194-
for element in array {
195-
self.append(element)
202+
for element in array {
203+
self.append(element)
204+
}
196205
}
197-
}
198206
}

0 commit comments

Comments
 (0)