Skip to content

Instantly share code, notes, and snippets.

@bmitchelmore
Last active August 23, 2019 04:41
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 bmitchelmore/154bfa8af44de79aca7bf0681af5075e to your computer and use it in GitHub Desktop.
Save bmitchelmore/154bfa8af44de79aca7bf0681af5075e to your computer and use it in GitHub Desktop.
Constant time OrderedSet
struct OrderedSet<T: Hashable> {
private class Link {
var previous: Link?
var next: Link?
var value: T
init(value: T) {
self.value = value
}
}
private var pos : [T:Link] = [:]
private var head : Link?
private var tail : Link?
func contains(value: T) -> Bool {
return pos[value] != nil
}
mutating func add(value: T) {
if pos[value] == nil {
let link = Link(value: value)
if let head = self.head {
link.next = head
head.previous = link
self.head = link
} else {
self.head = link;
}
if self.tail == nil {
self.tail = link
}
pos[value] = link
}
}
mutating func remove(value: T) {
if let link = pos[value] {
if link === self.head && link === self.tail {
self.head = nil
self.tail = nil
} else if link === self.head {
link.next?.previous = nil
self.head = link.next
} else if link === self.tail {
link.previous?.next = nil
self.tail = link.previous
} else {
link.previous?.next = link.next
link.next?.previous = link.previous
}
}
pos[value] = nil
}
var count : Int {
get {
return pos.count
}
}
var array : [T] {
get {
var array : [T] = [];
var link = tail
while link != nil {
guard let current = link else { break }
array.append(current.value)
link = current.previous
}
return array
}
}
init(values: [T] = []) {
for value in values {
add(value: value)
}
}
}
@bmitchelmore
Copy link
Author

bmitchelmore commented Oct 13, 2016

Using a bidirectional linked list to keep track of order and a dictionary to provide a uniqueness test along with constant time access to arbitrary locations in the linked list, we can have constant time insertion and deletion in an ordered set.

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