Last active
August 29, 2015 14:05
-
-
Save rjchatfield/ff21897f43b7e5ff8245 to your computer and use it in GitHub Desktop.
A Linked List in Swift
This file contains hidden or 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
// LINKED LIST | |
/** | |
* NODE | |
*/ | |
private class Node<T:protocol<Printable, Comparable>>: Printable, Comparable { | |
/** | |
* PROPERTIES | |
*/ | |
var info:T | |
var next:Node<T>? | |
/** | |
* INITIALISERS | |
*/ | |
init (info:T) { | |
self.info = info | |
} | |
/** | |
* PROTOCOL: Printable | |
*/ | |
var description: String { | |
return "\(self.info)" | |
} | |
} | |
private func ==<T:Comparable> (lhs: Node<T>, rhs: Node<T>) -> Bool { | |
return lhs.info == rhs.info | |
} | |
private func <=<T:Comparable> (lhs: Node<T>, rhs: Node<T>) -> Bool { | |
return lhs.info <= rhs.info | |
} | |
private func >=<T:Comparable> (lhs: Node<T>, rhs: Node<T>) -> Bool { | |
return lhs.info >= rhs.info | |
} | |
private func ><T:Comparable> (lhs: Node<T>, rhs: Node<T>) -> Bool { | |
return lhs.info > rhs.info | |
} | |
private func <<T:Comparable> (lhs: Node<T>, rhs: Node<T>) -> Bool { | |
return lhs.info < rhs.info | |
} | |
/** | |
* LinkedList | |
*/ | |
class LinkedList<T:protocol<Printable, Comparable>>:Printable { | |
/** | |
* PROPERTIES | |
*/ | |
private var root:Node<T>? | |
private var count:Int { | |
var _count = 0 | |
traverse { $0; _count++ } // neglect the value while traversing | |
return _count | |
} | |
/** | |
* INITIALISERS | |
*/ | |
init () {} | |
init (_ values:T ...) { | |
for value in values { | |
self.insert(value, atIndex: count) | |
} | |
} | |
/** | |
* FUNCTIONS | |
*/ | |
func traverse (task:(T)->Void) { | |
if let root = self.root { | |
task (root.info) | |
var nextptr = root | |
while let next = nextptr.next { | |
task (next.info) | |
nextptr = next | |
} | |
} | |
} | |
func insert (value:T, atIndex index:Int) { | |
if count < index || index < 0 { | |
println("Index outside of bounds") | |
return | |
} | |
if let root = self.root { | |
if index == 0 { | |
self.root = Node (info: value) | |
self.root?.next = root | |
} | |
else { | |
// Loop through and find the node at index | |
var node = root | |
for var i = 1; i < index; i++ { | |
if let thisNode = node.next { | |
node = thisNode | |
} | |
else { | |
break | |
} | |
} | |
// Insert after node | |
if let next = node.next { | |
node.next = Node (info: value) | |
node.next?.next = next | |
} | |
else { | |
node.next = Node (info: value) | |
} | |
} | |
} | |
else { | |
self.root = Node (info: value) | |
} | |
} | |
func append (values:T ...) { | |
for value in values { | |
insert(value, atIndex: count) | |
} | |
} | |
func prepend (values:T ...) { | |
for value in values.reverse() { | |
insert(value, atIndex: 0) | |
} | |
} | |
/** | |
* PROTOCOL: Printable | |
*/ | |
var description: String { | |
if let root = self.root { | |
var _description = "" | |
traverse { _description += "\($0) " } | |
return _description | |
} | |
else { | |
return "I'm not a tree yet" | |
} | |
} | |
} | |
/** | |
* MAIN LOGIC | |
*/ | |
let linkedList = LinkedList () as LinkedList<Int> ; println (linkedList) | |
linkedList.append (1,2,3) ; println (linkedList) | |
linkedList.append (4) ; println (linkedList) | |
linkedList.append (5) ; println (linkedList) | |
linkedList.prepend (-1, 0) ; println (linkedList) | |
linkedList.insert (10, atIndex: 3) ; println (linkedList) | |
linkedList.insert (100, atIndex: 10) ; println (linkedList) | |
linkedList.insert (100, atIndex: linkedList.count) ; println (linkedList) | |
var sum = 0 | |
linkedList.traverse { sum += $0 } | |
println("sum: \(sum)") | |
let linkedList2 = LinkedList (10,11,12,13,14,15,16) | |
println (linkedList2) | |
//-- PROGRAM OUTPUT --// | |
// I'm not a tree yet | |
// 1 2 3 | |
// 1 2 3 4 | |
// 1 2 3 4 5 | |
// -1 0 1 2 3 4 5 | |
// -1 0 1 10 2 3 4 5 | |
// Index outside of bounds | |
// -1 0 1 10 2 3 4 5 | |
// -1 0 1 10 2 3 4 5 100 | |
// sum: 124 | |
// 10 11 12 13 14 15 16 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Realised my prepend was inserting in the incorrect order. All fixed. Doesn't implement SequenceType. Didn't know where to start to implement the generator and a subscript. Nor have I implemented the ability to remove or read values. Pretty awesome, huh?