Mercurial > hgrepos > FreeBSD > ports > sysutils > local-bsdtools
changeset 774:75a8b69c04f0
farray.sh: Implement Shell sort using Ciura gaps (A102549)
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Wed, 23 Oct 2024 22:52:14 +0200 |
| parents | bae0652d0577 |
| children | ff36742b9955 |
| files | share/local-bsdtools/farray.sh tests/farray-array.t |
| diffstat | 2 files changed, 103 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/share/local-bsdtools/farray.sh Wed Oct 23 18:33:38 2024 +0200 +++ b/share/local-bsdtools/farray.sh Wed Oct 23 22:52:14 2024 +0200 @@ -1627,6 +1627,7 @@ _farr_array_get_meta "$@" + # XXX TBD: Select a method depenting on `__farr_len`. _farr_array_gnomesort } @@ -1655,6 +1656,8 @@ #: #: Internal sort implementation using Gnome Sort. #: +#: Stable: yes +#: #: This is a very simple stable sort (a variant of insertion sort). #: #: See: https://en.wikipedia.org/wiki/Gnome_sort @@ -1692,6 +1695,96 @@ #: +#: Sort an array using Shell Sort. +#: +#: Args: +#: $1: The array to sort to +#: +#: See Also: +#: `_farr_array_shellsort` +#: +farray_shellsort() { + local __farr_name + + local __farr_token __farr_gvrname __farr_len \ + __farr_pos __farr_val __farr_val_1 + + _farr_array_get_meta "$@" + + _farr_array_shellsort +} + + +#: +#: Internal sort implementation using Shell Sort. +#: +#: Used gap sequence: A102549 (Optimal (best known) sequence of increments +#: for shell sort algorithm.) (aka Ciura gap sequence) +#: +#: Stable: no +#: +#: See: - https://en.wikipedia.org/wiki/Shellsort +#: - https://oeis.org/A102549 +#: +#: Input (Globals): +#: All the "Output (Globals)" from `farr_array_get_meta`: +#: __farr_name, __farr_token, __farr_gvrname and __farr_len. +#: These variables are declared local in this function but the shell +#: initializes them from the same variables in the nearest dynamic scope. +#: So they are really input variables and not also output variables. +#: +_farr_array_shellsort() { + + local __farr_name __farr_token __farr_gvrname __farr_len \ + gaps_ciura \ + gap i j tmpitem tmpgapitem + + # + # XXX TBD: For larger length extend with A366726 (which are further + # optimized Tokuda good gaps. + # Or use a completely other sort (heap sort, et al.) + # + gaps_ciura="1750 701 301 132 57 23 10 4 1" + + # + # Start with the largest gap and work down to a gap of 1 similar + # to insertion sort but instead of 1, gap is being used in each + # step + # + for gap in ${gaps_ciura}; do + # + # Do a gapped insertion sort for every elements in gaps; + # each loop leaves a[1..gap] in gapped order + # + i=$((gap + 1)) + while [ "${i}" -le "${__farr_len}" ]; do + # Save a[i] in temp and make a hole at position i + eval tmpitem=\"\$\{"${__farr_gvrname}"_"${i}"\}\" + # + # Shift earlier gap-sorted elements up until the correct + # location for a[i] is found + # + j="${i}" + while true; do + [ "${j}" -le "${gap}" ] && break + eval tmpgapitem=\"\$\{"${__farr_gvrname}"_$((j - gap))\}\" + [ "${tmpgapitem}" = "${tmpitem}" ] || [ "${tmpgapitem}" '<' "${tmpitem}" ] && break +# if [ "${tmpgapitem}" = "${tmpitem}" ] || [ "${tmpgapitem}" '<' "${tmpitem}" ] ; then +# break + # fi + + setvar "${__farr_gvrname}"_"${j}" "${tmpgapitem}" + j=$((j - gap)) + done + # Put temp (the original a[i]) in its correct location + setvar "${__farr_gvrname}"_"${j}" "${tmpitem}" + i=$((i + 1)) + done + done +} + + +#: #: Try to find the index of a given value in an existing array. #: #: It assumes that the array is sorted and uses a binary search algorithm
--- a/tests/farray-array.t Wed Oct 23 18:33:38 2024 +0200 +++ b/tests/farray-array.t Wed Oct 23 22:52:14 2024 +0200 @@ -1402,10 +1402,20 @@ $ farray_create TEST $ farray_splice "" TEST 1 "" UNSORTED + $ check_array_is_sorted "$TEST" + [1] $ farray_gnomesort TEST $ check_array_is_sorted "$TEST" $ farray_release TEST + $ farray_create TEST + $ farray_splice "" TEST 1 "" UNSORTED + $ check_array_is_sorted "$TEST" + [1] + $ farray_shellsort TEST + $ check_array_is_sorted "$TEST" + $ farray_release TEST + $ farray_release UNSORTED $ check_no_array_artifacts
