Skip to content

Instantly share code, notes, and snippets.

@volonbolon
Created December 8, 2017 19:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save volonbolon/f220ddb3a9600a6643f73420a846086a to your computer and use it in GitHub Desktop.
Save volonbolon/f220ddb3a9600a6643f73420a846086a to your computer and use it in GitHub Desktop.
How to reverse a singly linked list
//: 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