import Foundation
class Node<Value> {
var value: Value
var next: Node?
init(value: Value, next: Node? = nil) {
self.value = value
self.next = next
}
}
extension Node: CustomStringConvertible {
var description: String {
guard let next = next else {
return "\(value)"
}
return "\(value) -> " + String(describing: next) + " "
}
}
struct LinkedList<Value: Comparable> {
var head: Node<Value>?
var tail: Node<Value>?
var isEmpty: Bool {
return head == nil
}
mutating func push(_ value: Value) {
head = Node(value: value, next: head)
if tail == nil {
tail = head
}
}
mutating func append(_ value: Value) {
copyNodes()
guard !isEmpty else {
push(value)
return
}
tail!.next = Node(value: value)
tail = tail!.next
}
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
mutating func insert(_ value: Value, after node: Node<Value>) -> Node<Value> {
copyNodes()
guard tail !== node else {
append(value)
return tail!
}
node.next = Node(value: value, next: node.next)
return node.next!
}
@discardableResult
mutating func pop() -> Value? {
copyNodes()
defer {
head = head?.next
if isEmpty {
tail = nil
}
}
return head?.value
}
@discardableResult
mutating func removeLast() -> Value? {
copyNodes()
guard let head = head, 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
mutating func remove(after node: Node<Value>) -> Value? {
copyNodes()
defer {
if node.next === tail {
tail = node
}
node.next = node.next?.next
}
return node.next?.value
}
mutating func copyNodes() {
guard !isKnownUniquelyReferenced(&head) else {return}
guard var oldNode = head else {return}
head = Node(value: oldNode.value)
var newNode = head
while let nextOldeNode = oldNode.next {
newNode?.next = Node(value: nextOldeNode.value)
newNode = newNode?.next
oldNode = nextOldeNode
}
tail = newNode
}
private func printInReverse<T>(_ node: Node<T>?) {
guard let node = node else {return}
printInReverse(node.next)
print(node.value)
}
func getMiddle<T>(_ list: LinkedList<T>) -> Node<T>? {
var slow = list.head // define a slow pointer
var fast = list.head // define a fast pointer
while let nextFast = fast?.next { // move fast poiner
fast = nextFast.next // move fast pointer again
slow = slow?.next // move slow pointer
}
return slow // return slow pointer
}
mutating func reverse() {
var prev = head // prev point to head
var current = head?.next // current point to next
tail = head // set new tail
tail?.next = nil // set new tail next nil
while current != nil { // loop until current is nil
let next = current?.next // find the next node
current?.next = prev // reverse next pointer
prev = current // moving prev forward
current = next // moving next forward
}
head = prev // since current is nil, new head is prev
}
mutating func remove(_ value: Value) {
while let head = head, head.value == value { // keep moving head until it does not equal to value
self.head = head.next
}
var prev = head // prev pointer, point to head
var current = head?.next // current pointer, point to next
while let currentNode = current { // loop through the list
guard currentNode.value != value else { // if current value = value
prev?.next = currentNode.next // prev next point to current next
current = prev?.next // set current to prev next
continue
}
prev = current // move prev forward
current = current?.next // move current forward
}
tail = prev // set tail as prev, since current is nil, so prev is the last node
}
}
Swift單向鏈表實現
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.