Skip to content

Commit

Permalink
Merge pull request kodecocodes#250 from ivanicspeter92/master
Browse files Browse the repository at this point in the history
Migrate Linked List to Swift 3.0
  • Loading branch information
kelvinlauKL authored Oct 10, 2016
2 parents bf9ba31 + 0fa2623 commit bad00fe
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 88 deletions.
39 changes: 18 additions & 21 deletions Linked List/LinkedList.playground/Contents.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public class LinkedList<T> {
}
}

public func nodeAt(_ index: Int) -> Node? {
public func node(atIndex index: Int) -> Node? {
if index >= 0 {
var node = head
var i = index
Expand All @@ -61,12 +61,12 @@ public class LinkedList<T> {
}

public subscript(index: Int) -> T {
let node = nodeAt(index)
let node = self.node(atIndex: index)
assert(node != nil)
return node!.value
}

public func append(value: T) {
public func append(_ value: T) {
let newNode = Node(value: value)
if let lastNode = last {
newNode.previous = lastNode
Expand All @@ -93,7 +93,7 @@ public class LinkedList<T> {
return (prev, next)
}

public func insert(value: T, atIndex index: Int) {
public func insert(_ value: T, atIndex index: Int) {
let (prev, next) = nodesBeforeAndAfter(index: index)

let newNode = Node(value: value)
Expand Down Expand Up @@ -132,8 +132,8 @@ public class LinkedList<T> {
return remove(node: last!)
}

public func removeAt(_ index: Int) -> T {
let node = nodeAt(index)
public func remove(atIndex index: Int) -> T {
let node = self.node(atIndex: index)
assert(node != nil)
return remove(node: node!)
}
Expand Down Expand Up @@ -168,7 +168,7 @@ extension LinkedList {
let result = LinkedList<U>()
var node = head
while node != nil {
result.append(value: transform(node!.value))
result.append(transform(node!.value))
node = node!.next
}
return result
Expand All @@ -179,29 +179,26 @@ extension LinkedList {
var node = head
while node != nil {
if predicate(node!.value) {
result.append(value: node!.value)
result.append(node!.value)
}
node = node!.next
}
return result
}
}




let list = LinkedList<String>()
list.isEmpty // true
list.first // nil
list.last // nil

list.append(value: "Hello")
list.append("Hello")
list.isEmpty
list.first!.value // "Hello"
list.last!.value // "Hello"
list.count // 1

list.append(value: "World")
list.append("World")
list.first!.value // "Hello"
list.last!.value // "World"
list.count // 2
Expand All @@ -211,24 +208,24 @@ list.first!.next!.value // "World"
list.last!.previous!.value // "Hello"
list.last!.next // nil

list.nodeAt(0)!.value // "Hello"
list.nodeAt(1)!.value // "World"
list.nodeAt(2) // nil
list.node(atIndex: 0)!.value // "Hello"
list.node(atIndex: 1)!.value // "World"
list.node(atIndex: 2) // nil

list[0] // "Hello"
list[1] // "World"
//list[2] // crash!

list.insert(value: "Swift", atIndex: 1)
list.insert("Swift", atIndex: 1)
list[0]
list[1]
list[2]
print(list)

list.reverse() // [World, Swift, Hello]

list.nodeAt(0)!.value = "Universe"
list.nodeAt(1)!.value = "Swifty"
list.node(atIndex: 0)!.value = "Universe"
list.node(atIndex: 1)!.value = "Swifty"
let m = list.map { s in s.characters.count }
m // [8, 6, 5]
let f = list.filter { s in s.characters.count > 5 }
Expand All @@ -237,7 +234,7 @@ f // [Universe, Swifty]
//list.removeAll()
//list.isEmpty

list.remove(node: list.first!) // "Hello"
list.remove(node: list.first!) // "Hello"
list.count // 2
list[0] // "Swift"
list[1] // "World"
Expand All @@ -246,5 +243,5 @@ list.removeLast() // "World"
list.count // 1
list[0] // "Swift"

list.removeAt(0) // "Swift"
list.remove(atIndex: 0) // "Swift"
list.count // 0
97 changes: 46 additions & 51 deletions Linked List/LinkedList.swift
Original file line number Diff line number Diff line change
@@ -1,32 +1,27 @@
/*
Doubly-linked list

Most operations on the linked list have complexity O(n).
*/
open class LinkedListNode<T> {
public class LinkedListNode<T> {
var value: T
var next: LinkedListNode?
weak var previous: LinkedListNode?

public init(value: T) {
self.value = value
}
}

open class LinkedList<T> {
public class LinkedList<T> {
public typealias Node = LinkedListNode<T>

fileprivate var head: Node?

open var isEmpty: Bool {
public var isEmpty: Bool {
return head == nil
}

open var first: Node? {
public var first: Node? {
return head
}

open var last: Node? {
public var last: Node? {
if var node = head {
while case let next? = node.next {
node = next
Expand All @@ -36,8 +31,8 @@ open class LinkedList<T> {
return nil
}
}

open var count: Int {
public var count: Int {
if var node = head {
var c = 1
while case let next? = node.next {
Expand All @@ -49,8 +44,8 @@ open class LinkedList<T> {
return 0
}
}

open func nodeAt(_ index: Int) -> Node? {
public func node(atIndex index: Int) -> Node? {
if index >= 0 {
var node = head
var i = index
Expand All @@ -62,14 +57,14 @@ open class LinkedList<T> {
}
return nil
}

open subscript(index: Int) -> T {
let node = nodeAt(index)
public subscript(index: Int) -> T {
let node = self.node(atIndex: index)
assert(node != nil)
return node!.value
}

open func append(_ value: T) {
public func append(_ value: T) {
let newNode = Node(value: value)
if let lastNode = last {
newNode.previous = lastNode
Expand All @@ -78,67 +73,67 @@ open class LinkedList<T> {
head = newNode
}
}

fileprivate func nodesBeforeAndAfter(_ index: Int) -> (Node?, Node?) {
private func nodesBeforeAndAfter(index: Int) -> (Node?, Node?) {
assert(index >= 0)

var i = index
var next = head
var prev: Node?

while next != nil && i > 0 {
i -= 1
prev = next
next = next!.next
}
assert(i == 0) // if > 0, then specified index was too large

return (prev, next)
}

open func insert(_ value: T, atIndex index: Int) {
let (prev, next) = nodesBeforeAndAfter(index)

public func insert(_ value: T, atIndex index: Int) {
let (prev, next) = nodesBeforeAndAfter(index: index)
let newNode = Node(value: value)
newNode.previous = prev
newNode.next = next
prev?.next = newNode
next?.previous = newNode

if prev == nil {
head = newNode
}
}

open func removeAll() {
public func removeAll() {
head = nil
}

open func remove(_ node: Node) -> T {
public func remove(node: Node) -> T {
let prev = node.previous
let next = node.next

if let prev = prev {
prev.next = next
} else {
head = next
}
next?.previous = prev

node.previous = nil
node.next = nil
return node.value
}

open func removeLast() -> T {
public func removeLast() -> T {
assert(!isEmpty)
return remove(last!)
return remove(node: last!)
}

open func removeAt(_ index: Int) -> T {
let node = nodeAt(index)
public func remove(atIndex index: Int) -> T {
let node = self.node(atIndex: index)
assert(node != nil)
return remove(node!)
return remove(node: node!)
}
}

Expand Down Expand Up @@ -167,17 +162,17 @@ extension LinkedList {
}

extension LinkedList {
public func map<U>(_ transform: (T)-> U) -> LinkedList<U> {
public func map<U>(transform: (T) -> U) -> LinkedList<U> {
let result = LinkedList<U>()
var node = head
while node != nil {
result.append(transform(node!.value))
result.append(transform(node!.value))
node = node!.next
}
return result
}

public func filter(_ predicate: (T)-> Bool) -> LinkedList<T> {
public func filter(predicate: (T) -> Bool) -> LinkedList<T> {
let result = LinkedList<T>()
var node = head
while node != nil {
Expand Down
Loading

0 comments on commit bad00fe

Please sign in to comment.