Skip to content

Commit cedc141

Browse files
authored
Add counting sort (#38)
1 parent b7bf87b commit cedc141

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

Diff for: .spec/sorting/sort_spec.lua

+3
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,6 @@ end)
7575
describe("Bogosort", function()
7676
check_sort(require("sorting.bogosort"), 5)
7777
end)
78+
describe("Countingsort", function()
79+
check_sort(require("sorting.countingsort"), nil, true)
80+
end)

Diff for: src/sorting/countingsort.lua

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
return function(
2+
-- list to be sorted in-place
3+
list,
4+
-- key_function to map elements to integer keys, defaults to identity
5+
key_function
6+
)
7+
if list[1] == nil then
8+
return
9+
end
10+
11+
key_function = key_function or function(x)
12+
return x
13+
end
14+
15+
-- Find the range of keys (min_key and max_key)
16+
local min_key, max_key = math.huge, -math.huge
17+
for _, elem in ipairs(list) do
18+
local key = key_function(elem)
19+
min_key = math.min(min_key, key)
20+
max_key = math.max(max_key, key)
21+
end
22+
23+
local count = {}
24+
for i = 1, max_key - min_key + 1 do
25+
count[i] = 0
26+
end
27+
28+
-- Count the occurrences of each key
29+
for _, elem in ipairs(list) do
30+
local key = key_function(elem)
31+
count[key - min_key + 1] = count[key - min_key + 1] + 1
32+
end
33+
34+
-- Compute cumulative counts for final positions
35+
for i = 2, #count do
36+
count[i] = count[i] + count[i - 1]
37+
end
38+
39+
local output = {}
40+
for i = #list, 1, -1 do
41+
local element = list[i]
42+
local key = key_function(element)
43+
output[count[key - min_key + 1]] = element
44+
count[key - min_key + 1] = count[key - min_key + 1] - 1
45+
end
46+
47+
for i, elem in ipairs(output) do
48+
list[i] = elem
49+
end
50+
end

0 commit comments

Comments
 (0)