Mercurial > lbo > hg > juliaplay
changeset 1:ed34696a9d9b
Some better sorting
author | Lewin Bormann <lbo@spheniscida.de> |
---|---|
date | Sun, 12 Feb 2023 20:12:55 +0100 |
parents | d0c890aae379 |
children | b7160d5e22cc |
files | mergesort.jl quicksort.jl strings.jl |
diffstat | 3 files changed, 69 insertions(+), 15 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mergesort.jl Sun Feb 12 20:12:55 2023 +0100 @@ -0,0 +1,46 @@ + +function merge!(a::AbstractArray, mid::Int, aux::Union{AbstractArray, Nothing}=nothing) + if length(a) <= 1 + return + end + # Left half: begin:mid + # Right half: mid+1:end + left, right, i = 1, mid+1, 1 + ac = isnothing(aux) ? copy(a) : aux + while i <= length(a) + if left > mid + ac[i] = a[right] + right += 1 + elseif right > length(a) + ac[i] = a[left] + left += 1 + else + if a[left] < a[right] + ac[i] = a[left] + left += 1 + else + ac[i] = a[right] + right += 1 + end + end + i += 1 + end + for i = eachindex(a) + a[i] = ac[i] + end +end + +function mergesort!(a::AbstractArray) + aux = copy(a) + if length(a) <= 1 + return + elseif length(a) == 2 + a[1], a[2] = (a[1] < a[2] ? (a[1],a[2]) : (a[2],a[1])) + return + else + mid = div(1+length(a), 2) + mergesort!(@view a[begin:mid]) + mergesort!(@view a[mid+1:end]) + merge!(a, mid, aux) + end +end
--- a/quicksort.jl Sat Nov 26 09:23:14 2022 +0100 +++ b/quicksort.jl Sun Feb 12 20:12:55 2023 +0100 @@ -1,12 +1,24 @@ +function partition(v::Vector{T}, from::Int, to::Int)::Int where {T} + piv = v[to] + i = from-1 + for j = from:to-1 + if v[j] <= piv + i += 1 + v[i], v[j] = v[j], v[i] + end + end + i += 1 + v[i], v[to] = v[to], v[i] + i +end -function partition(v::Vector{T}, from::Int, to::Int)::Int where {T} - if to-from < 1 +function hoare!(v::AbstractArray, from::Int, to::Int)::Int + if from >= to return from end lo, hi = from-1, to+1 - mid = round(Int, (lo+hi)/2) - piv = v[mid] - while lo < hi + piv = v[div(from+to,2)] + while true lo += 1 while v[lo] < piv lo += 1 @@ -20,24 +32,18 @@ end v[lo], v[hi] = v[hi], v[lo] end - lo end function quicksort!(v::Vector{T}, from=1, to=-1) where {T} if to < 0 to = length(v) end - if to-from == 1 + if to <= from return else - mid = partition(v, from, to) - @show (from, to, mid) - if from < mid - quicksort!(v, from, mid) - end - if mid+1 < to - quicksort!(v, mid+1, to) - end + mid = hoare!(v, from, to) + quicksort!(v, from, mid) + quicksort!(v, mid+1, to) end end