Skip to content

Instantly share code, notes, and snippets.

@sketchytech
Last active October 3, 2016 12:48
Show Gist options
  • Save sketchytech/3e8de36cc488576e4257e2fee855f450 to your computer and use it in GitHub Desktop.
Save sketchytech/3e8de36cc488576e4257e2fee855f450 to your computer and use it in GitHub Desktop.
Airspeed Velocity's Stable Sort updated to Swift 3
// Swift 2 stable sort taken from AirspeedVelocity blog and updated to Swift 3
// http://airspeedvelocity.net/2016/01/10/writing-a-generic-stable-sort/
extension RangeReplaceableCollection
where
Index: Strideable,
SubSequence.Iterator.Element == Iterator.Element,
IndexDistance == Index.Stride {
public mutating func stableSortInPlace(
isOrderedBefore: @escaping (Iterator.Element,Iterator.Element)->Bool
) {
let N = self.count
var aux: [Iterator.Element] = []
aux.reserveCapacity(numericCast(N))
func merge(lo: Index, mid: Index, hi: Index) {
aux.removeAll(keepingCapacity: true)
var i = lo, j = mid
while i < mid && j < hi {
if isOrderedBefore(self[j],self[i]) {
aux.append(self[j])
j = (j as! Int + 1) as! Self.Index
}
else {
aux.append(self[i])
i = (i as! Int + 1) as! Self.Index
}
}
aux.append(contentsOf:self[i..<mid])
aux.append(contentsOf:self[j..<hi])
self.replaceSubrange(lo..<hi, with: aux)
}
var sz: IndexDistance = 1
while sz < N {
for lo in stride(from:startIndex, to: endIndex-sz, by: sz*2) {
if lo.advanced(by:sz*2) >= endIndex {
break
}
merge(lo:lo, mid: lo+sz, hi:lo.advanced(by:sz*2))
}
sz *= 2
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment