1313 * import { mergeInsertionSort, Comparator } from 'merge-insertion'
1414 *
1515 * // A Comparator must return 0 if the first item is larger, or 1 if the second item is larger.
16+ * // It can use any criteria for comparison, including user input, this is just a simple example:
1617 * const comp :Comparator<string> = async ([a, b]) => a > b ? 0 : 1
1718 *
1819 * // Sort five items in ascending order with a maximum of only seven comparisons:
2728 * Addison-Wesley. <https://cs.stanford.edu/~knuth/taocp.html#vol3>
2829 * 3. <https://en.wikipedia.org/wiki/Merge-insertion_sort>
2930 *
31+ * See Also
32+ * --------
33+ *
34+ * * Python version: <https://pypi.org/project/merge-insertion/>
35+ *
36+ * * This algorithm in action: <https://haukex.github.io/pairrank/> (select "Efficient")
37+ *
3038 * Author, Copyright and License
3139 * -----------------------------
3240 *
@@ -77,7 +85,7 @@ export function* _groupSizes() :Generator<number, never, never> {
7785}
7886
7987/** Helper function to group and reorder items to be inserted via binary search.
80- * See also the description in the code of {@link mergeInsertionSort}.
88+ * See also the description within the code of {@link mergeInsertionSort}.
8189 * @internal */
8290export function _makeGroups < T > ( array :ReadonlyArray < T > ) :[ origIdx :number , item :T ] [ ] {
8391 const items :ReadonlyArray < [ number , T ] > = array . map ( ( e , i ) => [ i , e ] )
@@ -124,6 +132,7 @@ export async function _binInsertIdx<T extends Comparable>(array :ReadonlyArray<T
124132 * @returns A Promise resolving to a shallow copy of the array sorted in ascending order.
125133 */
126134export async function mergeInsertionSort < T extends Comparable > ( array :ReadonlyArray < T > , comparator :Comparator < T > ) :Promise < T [ ] > {
135+ // Special cases and error checking
127136 if ( array . length < 1 ) return [ ]
128137 if ( array . length == 1 ) return Array . from ( array )
129138 if ( array . length != new Set ( array ) . size ) throw new Error ( 'array may not contain duplicate items' )
@@ -213,7 +222,7 @@ export async function mergeInsertionSort<T extends Comparable>(array :ReadonlyAr
213222 else {
214223 // Locate the pair we're about to insert in the main chain, to limit the extent of the binary search (see also explanation above).
215224 const pairIdx = mainChain . findIndex ( v => Object . is ( v , pair ) )
216- // Locate the index in the main chain where the pair's smaller item needs to be inserted, and insert it .
225+ // Locate the index in the main chain where the pair's smaller item needs to be inserted.
217226 return [ pair . smaller , await _binInsertIdx ( mainChain . slice ( 0 , pairIdx ) . map ( p => p . item ) , pair . smaller , comparator ) ]
218227 }
219228 } ) ( )
@@ -235,7 +244,7 @@ export async function mergeInsertionSort<T extends Comparable>(array :ReadonlyAr
235244 */
236245export function mergeInsertionMaxComparisons ( n :number ) :number {
237246 if ( n < 0 ) throw new Error ( 'must specify zero or more items' )
238- // formulas from https://en.wikipedia.org/wiki/Merge-insertion_sort (both of the following work):
247+ // Formulas from https://en.wikipedia.org/wiki/Merge-insertion_sort (both of the following work):
239248 /*let C = 0
240249 for (let i=1; i<=n; i++)
241250 C += Math.ceil(Math.log2((3*i)/4))
0 commit comments