Skip to content

Commit 9bcdc06

Browse files
committed
Add Mergesort
1 parent f3a87e3 commit 9bcdc06

File tree

2 files changed

+55
-0
lines changed

2 files changed

+55
-0
lines changed

.spec/sorting/sort_spec.lua

+3
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ end
2323
describe("Heapsort", function()
2424
check_sort(require("sorting.heapsort"))
2525
end)
26+
describe("Mergesort", function()
27+
check_sort(require("sorting.mergesort"))
28+
end)
2629
describe("Quicksort", function()
2730
check_sort(require("sorting.quicksort")())
2831
end)

src/sorting/mergesort.lua

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
return function(
2+
-- list to be sorted in-place
3+
list,
4+
-- function(a, b) -> truthy value if a < b
5+
less_than
6+
)
7+
less_than = less_than or function(a, b)
8+
return a < b
9+
end
10+
-- Merges two sorted lists; elements of a come before those of b
11+
local function merge(result, list, other_list)
12+
local result_index = 1
13+
local index = 1
14+
local other_index = 1
15+
while index <= #list and other_index <= #other_list do
16+
-- Compare "head" element, insert "winner"
17+
if less_than(other_list[other_index], list[index]) then
18+
result[result_index] = other_list[other_index]
19+
other_index = other_index + 1
20+
else
21+
result[result_index] = list[index]
22+
index = index + 1
23+
end
24+
result_index = result_index + 1
25+
end
26+
-- Add remaining elements of either list or other_list
27+
for offset = 0, #list - index do
28+
result[result_index + offset] = list[index + offset]
29+
end
30+
for offset = 0, #other_list - other_index do
31+
result[result_index + offset] = other_list[other_index + offset]
32+
end
33+
end
34+
35+
local function mergesort(list_to_sort, lower_index, upper_index)
36+
if lower_index == upper_index then
37+
list_to_sort[1] = list[lower_index]
38+
end
39+
if lower_index >= upper_index then
40+
return
41+
end
42+
local middle_index = math.floor((upper_index + lower_index) / 2)
43+
44+
local left = {}
45+
mergesort(left, lower_index, middle_index)
46+
local right = {}
47+
mergesort(right, middle_index + 1, upper_index)
48+
49+
merge(list_to_sort, left, right)
50+
end
51+
mergesort(list, 1, #list)
52+
end

0 commit comments

Comments
 (0)