Created
September 20, 2018 16:04
-
-
Save Mohsenqaysi/38a3f24b5b290ee32ff505e222233be2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
// Linked List | |
// need to keep track of where the list begins and ends. | |
// value: data | |
// next and previous: poninters | |
public class Node { | |
var value: String // non-optional value | |
var next: Node? // must be optional so we can point to nil | |
weak var previous: Node? // waek ... to avoid ownership cycles | |
init(value: String){ | |
self.value = value | |
} | |
} | |
public class LinkedList { | |
fileprivate var head: Node? | |
fileprivate var tail: Node? | |
var isEmpty: Bool { | |
return head == nil | |
} | |
var first: Node? { | |
return head | |
} | |
var last: Node? { | |
return tail | |
} | |
// MARK: - Add new value to the list | |
func append(value: String){ | |
// create a new Node | |
let newNode = Node(value: value) | |
/* | |
If tailNode is not nil, that means there is something in the linked list already. | |
If that’s the case, configure the new item to point to the tail of the list as it’s previous item. | |
Similarly, configure the new last item on the list to point to the new node as it’s next item. | |
*/ | |
if let tailNode = tail { | |
newNode.previous = tailNode | |
tailNode.next = newNode | |
} else { | |
head = newNode | |
} | |
// Finally, set the tail of the list to be the new item in either case. | |
tail = newNode | |
} | |
//MARK: - Access value at index: | |
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 | |
} | |
func remove(node: Node) { | |
let prev = node.previous | |
let next = node.next | |
print("prev: \(prev?.value ?? "nil" ) <- '\(node.value)' -> next: \(next?.value ?? "nil")") | |
if let prev = prev { | |
prev.next = next | |
} else { | |
head = next | |
} | |
next?.previous = prev | |
if tail == nil { | |
tail = prev | |
} | |
node.next = nil | |
node.previous = nil | |
print(" '\(node.value)' was remove") | |
} | |
func removeAll() { | |
head = nil | |
tail = nil | |
} | |
} | |
var linkedList = LinkedList() // create new Linked List | |
// append new values | |
linkedList.append(value:"Mohsen") | |
linkedList.append(value:"Alex") | |
linkedList.append(value:"John") | |
linkedList.append(value:"Mark") | |
print(linkedList.isEmpty) | |
print(linkedList) | |
let nodeValue = linkedList.nodeAt(index: 2) | |
print(nodeValue!.value) | |
linkedList.remove(node: nodeValue!) | |
print(linkedList) | |
// CustomStringConvertible to help print the text in a nice format | |
extension LinkedList: CustomStringConvertible { | |
public var description: String { | |
var text = "head -> " | |
var node = head | |
while node != nil { | |
text += "\(node!.value)" | |
node = node!.next | |
if node != nil { text += " -> " } | |
} | |
return text + " -> nil" | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment