Skip to content

Instantly share code, notes, and snippets.

@aydin-emre
Created February 10, 2022 12:42
Show Gist options
  • Save aydin-emre/65cd15527e72aa5a9bfdffe4a8820c04 to your computer and use it in GitHub Desktop.
Save aydin-emre/65cd15527e72aa5a9bfdffe4a8820c04 to your computer and use it in GitHub Desktop.
LinkedList Example on iOS, written in Swift..
import UIKit
public class Node<Value> {
public var value: Value
public var next: Node?
public init(value: Value, next: Node? = nil) {
self.value = value
self.next = next
}
}
extension Node: CustomStringConvertible {
public var description: String {
guard let next = next else {
return "\(value)"
}
return "\(value) -> " + String(describing: next) + " "
}
}
public struct LinkedList<Value> {
public var head: Node<Value>?
public var tail: Node<Value>?
public init() {}
public mutating func push(_ value: Value) {
head = Node(value: value, next: head)
if tail == nil {
tail = head
}
}
public mutating func append(_ value: Value) {
guard !isEmpty else {
push(value)
return
}
tail!.next = Node(value: value)
tail = tail!.next
}
public func node(at index: Int) -> Node<Value>? {
var currentNode = head
var currentIndex = 0
while currentNode != nil && currentIndex < index {
currentNode = currentNode!.next
currentIndex += 1
}
return currentNode
}
@discardableResult
public mutating func insert(_ value: Value,
after node: Node<Value>)
-> Node<Value> {
guard tail !== node else {
append(value)
return tail!
}
node.next = Node(value: value, next: node.next)
return node.next!
}
@discardableResult
public mutating func pop() -> Value? {
defer {
head = head?.next
if isEmpty {
tail = nil
}
}
return head?.value
}
@discardableResult
public mutating func removeLast() -> Value? {
guard let head = head else {
return nil
}
guard head.next != nil else {
return pop()
}
var prev = head
var current = head
while let next = current.next {
prev = current
current = next
}
prev.next = nil
tail = prev
return current.value
}
@discardableResult
public mutating func remove(after node: Node<Value>) -> Value? {
defer {
if node.next === tail {
tail = node
}
node.next = node.next?.next
}
return node.next?.value
}
public var isEmpty: Bool {
head == nil
}
}
extension LinkedList: CustomStringConvertible {
public var description: String {
guard let head = head else {
return "Empty list"
}
return String(describing: head)
}
}
var list = LinkedList<Int>()
list.push(3)
list.push(2)
list.push(1)
list.append(4)
print("Before inserting: \(list)")
var middleNode = list.node(at: 1)!
middleNode = list.insert(4, after: middleNode)
print("After inserting: \(list)")
print("Before popping list: \(list)")
let poppedValue = list.pop()
print("After popping list: \(list)")
print("Popped value: " + String(describing: poppedValue))
print("Before removing last node: \(list)")
let removedValue = list.removeLast()
print("After removing last node: \(list)")
print("Removed value: " + String(describing: removedValue))
list.append(5)
list.append(6)
list.append(7)
print("Before removing at particular index: \(list)")
let index = 3
let node = list.node(at: index - 1)!
let removedValue1 = list.remove(after: node)
print("After removing at index \(index): \(list)")
print("Removed value: " + String(describing: removedValue1))
print("List1 uniquely referenced: \(isKnownUniquelyReferenced(&list.head))")
var list2 = list
print("List1 uniquely referenced: \(isKnownUniquelyReferenced(&list.head))")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment