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
 
--- a/strings.jl	Sat Nov 26 09:23:14 2022 +0100
+++ b/strings.jl	Sun Feb 12 20:12:55 2023 +0100
@@ -37,3 +37,5 @@
     end
     length(stack) == 0
 end
+
+