Reputation: 61
I'm not quite sure why my merge-sort implementation is not working.
merge_sort takes as arguments an array A, and starting and final indices p and r. If I try to run merge_sort(A, 1, 9) on A = [1, 64, 64, 315, 14, 2, 3, 4, 5], A will become A = [1, 1, 1, 1, 1, 2, 2, 4, 5]. I'm trying to use a sentinel to detect whether the L and R arrays have been exhausted.
Here is the code:
function merge_sort(A, p, r)
if p < r
q = floor(Int, (p+r)/2)
merge_sort(A, p, q)
merge_sort(A, q+1, r)
merge(A, p, q, r)
end
end
function merge(A, p, q, r)
n1 = q-p+1
n2 = r-q
L = []
R = []
for i = 1:n1
push!(L, A[p+1-1])
end
for j = 1:n2
push!(R, A[q+j])
end
sentinel = 123456789
push!(L, sentinel)
push!(R, sentinel)
i=1
j=1
for k=p:r
if L[i] <= R[j]
A[k] = L[i]
i = i+1
else
A[k] = R[j]
j = j+1
end
end
end
Upvotes: 4
Views: 729
Reputation: 69899
You have a typo in push!(L, A[p+1-1])
which should be push!(L, A[p+i-1])
.
Here is a bit cleaned up version of your code (but I did not try to fully optimize it to retain your logic):
function merge_sort!(A, p = 1, r = length(A))
if p < r
q = div(p+r, 2)
merge_sort!(A, p, q)
merge_sort!(A, q+1, r)
merge!(A, p, q, r)
end
A
end
function merge!(A, p, q, r)
sentinel = typemax(eltype(A))
L = A[p:q]
R = A[(q+1):r]
push!(L, sentinel)
push!(R, sentinel)
i, j = 1, 1
for k in p:r
if L[i] <= R[j]
A[k] = L[i]
i += 1
else
A[k] = R[j]
j += 1
end
end
end
Upvotes: 6