|
| 1 | +# Partial Sort |
| 2 | + |
| 3 | +[[Source](https://github.com/apple/swift-algorithms/blob/main/Sources/Algorithms/PartialSort.swift) | |
| 4 | + [Tests](https://github.com/apple/swift-algorithms/blob/main/Tests/SwiftAlgorithmsTests/PartialSortTests.swift)] |
| 5 | + |
| 6 | +Returns a collection such that the `0...k` range contains the first k sorted elements of a sequence. |
| 7 | +The order of equal elements is not guaranteed to be preserved, and the order of the remaining elements is unspecified. |
| 8 | + |
| 9 | +If you need to sort a sequence but only need access to a prefix of its elements, |
| 10 | +using this method can give you a performance boost over sorting the entire sequence. |
| 11 | + |
| 12 | +```swift |
| 13 | +let numbers = [7,1,6,2,8,3,9] |
| 14 | +let almostSorted = numbers.partiallySorted(3, <) |
| 15 | +// [1, 2, 3, 9, 7, 6, 8] |
| 16 | +``` |
| 17 | + |
| 18 | +## Detailed Design |
| 19 | + |
| 20 | +This adds the in place `MutableCollection` method shown below: |
| 21 | + |
| 22 | +```swift |
| 23 | +extension Sequence { |
| 24 | + func partiallySort(_ count: Int, by areInIncreasingOrder: (Element, Element) throws -> Bool) rethrows |
| 25 | +} |
| 26 | +``` |
| 27 | + |
| 28 | +Additionally, versions of this method that return a new array and abstractions for `Comparable` types are also provided: |
| 29 | + |
| 30 | +```swift |
| 31 | +extension MutableCollection where Self: RandomAccessCollection, Element: Comparable { |
| 32 | + public mutating func partiallySort(_ count: Int) |
| 33 | +} |
| 34 | + |
| 35 | +extension Sequence { |
| 36 | + public func partiallySorted(_ count: Int, by areInIncreasingOrder: (Element, Element) throws -> Bool) rethrows -> [Element] |
| 37 | +} |
| 38 | + |
| 39 | +extension Sequence where Element: Comparable { |
| 40 | + public func partiallySorted(_ count: Int) -> [Element] |
| 41 | +} |
| 42 | +``` |
| 43 | + |
| 44 | +### Complexity |
| 45 | + |
| 46 | +Partially sorting is a O(_k log n_) operation, where _k_ is the number of elements to sort |
| 47 | +and _n_ is the length of the sequence. |
| 48 | + |
| 49 | +`partiallySort(_:by:)` is a slight generalization of a priority queue. It's implemented |
| 50 | +as an in line heapsort that stops after _k_ runs. |
| 51 | + |
| 52 | +### Comparison with other languages |
| 53 | + |
| 54 | +**C++:** The `<algorithm>` library defines a `partial_sort` function with similar |
| 55 | +semantics to this one. |
| 56 | + |
| 57 | +**Python:** Defines a `heapq` priority queue that can be used to manually |
| 58 | +achieve the same result. |
| 59 | + |
0 commit comments