Created
December 8, 2017 19:57
-
-
Save volonbolon/f220ddb3a9600a6643f73420a846086a to your computer and use it in GitHub Desktop.
How to reverse a singly linked list
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
//: Playground - noun: a place where people can play | |
import UIKit | |
class Node<T: Equatable> { | |
typealias NodeType = Node<T> | |
let value: T | |
var next: NodeType? = nil | |
public init(value: T) { | |
self.value = value | |
} | |
} | |
extension Node: Equatable { | |
static func ==(lhs: Node, rhs: Node) -> Bool { | |
return lhs.value == rhs.value | |
} | |
} | |
extension Node: CustomStringConvertible { | |
var description: String { | |
return "Node(\(self.value))" | |
} | |
} | |
/** | |
This is a preposterous simple linked list implentation. | |
The only intention of it is to illstrate how to find loops | |
*/ | |
class LinkedList<T: Equatable> { | |
typealias NodeType = Node<T> | |
// TODO: We should add ivars for head, tail and even count | |
var head: NodeType? | |
init<S: Sequence>(_ elements: S) where S.Iterator.Element == T { | |
for element in elements { | |
self.preppend(value: element) | |
} | |
} | |
} | |
extension LinkedList { | |
func preppend(value: T) { | |
let node = NodeType(value: value) | |
if let head = self.head { | |
node.next = head | |
} | |
self.head = node | |
} | |
} | |
extension LinkedList: CustomStringConvertible { | |
var description: String { | |
guard self.head != nil else { | |
return "Empty List" | |
} | |
var description = "" | |
var currentNode:NodeType? = self.head | |
while currentNode != nil { | |
description += "\(currentNode!)->" | |
if let next = currentNode?.next { | |
currentNode = next | |
} else { | |
currentNode = nil | |
description += "nil" | |
} | |
} | |
return description | |
} | |
} | |
extension LinkedList { | |
// returns the head of the reversed lists (or nil if the list is empty) | |
func reversed() { | |
guard let head = self.head else { | |
return | |
} | |
var previousNode:NodeType? = nil | |
var currentNode:NodeType? = head | |
var nextNode:NodeType? = nil | |
while currentNode != nil { | |
// if there is a `next` nide, we keep moving | |
if let next = currentNode?.next { | |
nextNode = next | |
} else { | |
// but if we are at the last node, we reset the head of the list | |
self.head = currentNode | |
nextNode = nil | |
} | |
// Let's change the direction of the next pointer arrow | |
// In the first loop, `previousNode` marking the sentinel of the reversed list | |
currentNode?.next = previousNode | |
// and now, prev is pointing to current, and we move on | |
previousNode = currentNode | |
currentNode = nextNode | |
} | |
} | |
} | |
// Let's produce a list | |
let l:[Int] = Array(1...10) | |
// And with it, creates to Linked list | |
let linkedList = LinkedList(l.reversed()) | |
print(linkedList) // Node(1)->Node(2)->Node(3)->Node(4)->Node(5)->Node(6)->Node(7)->Node(8)->Node(9)->Node(10)->nil | |
linkedList.reversed() | |
print(linkedList) // Node(10)->Node(9)->Node(8)->Node(7)->Node(6)->Node(5)->Node(4)->Node(3)->Node(2)->Node(1)->nil |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment