Skip to content

Instantly share code, notes, and snippets.

@rjchatfield
Last active August 29, 2015 14:05
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 rjchatfield/ff21897f43b7e5ff8245 to your computer and use it in GitHub Desktop.
Save rjchatfield/ff21897f43b7e5ff8245 to your computer and use it in GitHub Desktop.
A Linked List in Swift
// 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
@rjchatfield
Copy link
Author

I couldn't find a way to move the Node declaration into the LinkedList declaration without breaking the infix operator implementations.

@rjchatfield
Copy link
Author

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment