diff --git a/Swift/Double.playground/Contents.swift b/Swift/Double.playground/Contents.swift new file mode 100644 index 0000000..e8c4921 --- /dev/null +++ b/Swift/Double.playground/Contents.swift @@ -0,0 +1,115 @@ +import Foundation + +public class LinkedList { + + public class Node { + var data: T + var next: Node? + weak var previous: Node? // weak to avoid memory leak. ARC do the trick. + // Every Node knows only its neighbours + + init(data: T) { + self.data = data + } + } + + fileprivate var head: Node? + private var tail: Node? // List knows its head and tail. + + public var isEmpty: Bool { + return head == nil + } + + public var first: Node? { + return head + } + + public var last: Node? { + return tail + } + + public func append(data: T) { + let newNode = Node(data: data) + if let tailNode = tail { + newNode.previous = tailNode + tailNode.next = newNode + } else { + head = newNode + } + tail = newNode + } + + + func removeAll() { // When head and tail is nil, weak ref will automatically delete its references one by one. + head = nil + tail = nil + } + + 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 + + if next == nil { + tail = prev + } + + node.previous = nil + node.next = nil + + return node.data + } + + + public func nodeAt(index: Int) -> Node? { + if index >= 0 { + var node = head + var i = index + while node != nil { + if i == 0 { return node } + i -= 1 + node = node!.next + } + } + return nil + } +} + +extension LinkedList: CustomStringConvertible { + + public var description: String { + + var text = "[" + var node = head + + while node != nil { + text += "\(node!.data)" + node = node!.next + if node != nil { text += ", " } + } + + return text + "]" + } +} + + +let myList = LinkedList() + + +myList.append(data: 1231) +myList.append(data: 3) +myList.append(data: 5) +myList.append(data: 10) + +print(myList) // [1231, 3, 5, 10] +let secondNode = myList.nodeAt(index: 1)?.data // 3 + +myList.removeAll() + +print(myList) // [] diff --git a/Swift/Double.playground/contents.xcplayground b/Swift/Double.playground/contents.xcplayground new file mode 100644 index 0000000..63b6dd8 --- /dev/null +++ b/Swift/Double.playground/contents.xcplayground @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/Swift/Double.playground/playground.xcworkspace/contents.xcworkspacedata b/Swift/Double.playground/playground.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..919434a --- /dev/null +++ b/Swift/Double.playground/playground.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Swift/Double.playground/playground.xcworkspace/xcuserdata/anastasia.xcuserdatad/UserInterfaceState.xcuserstate b/Swift/Double.playground/playground.xcworkspace/xcuserdata/anastasia.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..e5e04c9 Binary files /dev/null and b/Swift/Double.playground/playground.xcworkspace/xcuserdata/anastasia.xcuserdatad/UserInterfaceState.xcuserstate differ