Skip to content

Commit

Permalink
Added counting sort (#280)
Browse files Browse the repository at this point in the history
  • Loading branch information
czgdp1807 authored May 29, 2020
1 parent 5f5e386 commit 7e3a3cd
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 4 deletions.
3 changes: 2 additions & 1 deletion pydatastructs/linear_data_structures/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
brick_sort,
brick_sort_parallel,
heapsort,
matrix_multiply_parallel
matrix_multiply_parallel,
counting_sort
)
__all__.extend(algorithms.__all__)
82 changes: 80 additions & 2 deletions pydatastructs/linear_data_structures/algorithms.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from pydatastructs.linear_data_structures.arrays import (
OneDimensionalArray, DynamicArray)
OneDimensionalArray, DynamicArray, Array)
from pydatastructs.utils.misc_util import _check_type, _comp
from concurrent.futures import ThreadPoolExecutor
from math import log, floor
Expand All @@ -9,7 +9,8 @@
'brick_sort',
'brick_sort_parallel',
'heapsort',
'matrix_multiply_parallel'
'matrix_multiply_parallel',
'counting_sort'
]

def _merge(array, sl, el, sr, er, end, comp):
Expand Down Expand Up @@ -294,6 +295,83 @@ def heapsort(array, **kwargs):
if _check_type(array, DynamicArray):
array._modify(force=True)

def counting_sort(array: Array) -> Array:
"""
Performs counting sort on the given array.
Parameters
==========
array: Array
The array which is to be sorted.
Returns
=======
output: Array
The sorted array.
Examples
========
>>> from pydatastructs import DynamicOneDimensionalArray as DODA, counting_sort
>>> arr = DODA(int, [5, 78, 1, 0])
>>> out = counting_sort(arr)
>>> str(out)
"['0', '1', '5', '78']"
>>> arr.delete(2)
>>> out = counting_sort(arr)
>>> str(out)
"['0', '5', '78']"
References
==========
.. [1] https://en.wikipedia.org/wiki/Counting_sort
Note
====
Since, counting sort is a non-comparison sorting algorithm,
custom comparators aren't allowed.
The ouput array doesn't contain any `None` value.
"""
max_val, min_val = array[0], array[0]
none_count = 0
for i in range(len(array)):
if array[i] is not None:
if max_val is None or max_val < array[i]:
max_val = array[i]
if min_val is None or array[i] < min_val:
min_val = array[i]
else:
none_count += 1
if min_val is None or max_val is None:
return array

count = [0 for _ in range(max_val - min_val + 1)]
for i in range(len(array)):
if array[i] is not None:
count[array[i] - min_val] += 1

total = 0
for i in range(max_val - min_val + 1):
count[i], total = total, count[i] + total

output = type(array)(array._dtype,
[array[i] for i in range(len(array))
if array[i] is not None])
if _check_type(output, DynamicArray):
output._modify(force=True)

for i in range(len(array)):
x = array[i]
if x is not None:
output[count[x-min_val]] = x
count[x-min_val] += 1

return output

def _matrix_multiply_helper(m1, m2, row, col):
s = 0
for i in range(len(m1)):
Expand Down
16 changes: 15 additions & 1 deletion pydatastructs/linear_data_structures/tests/test_algorithms.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from pydatastructs import (
merge_sort_parallel, DynamicOneDimensionalArray,
OneDimensionalArray, brick_sort, brick_sort_parallel,
heapsort, matrix_multiply_parallel)
heapsort, matrix_multiply_parallel, counting_sort)
from pydatastructs.utils.raises_util import raises
import random

Expand Down Expand Up @@ -53,6 +53,20 @@ def test_brick_sort_parallel():
def test_heapsort():
_test_common_sort(heapsort)

def test_counting_sort():
random.seed(1000)

n = random.randint(10, 20)
arr = DynamicOneDimensionalArray(int, 0)
for _ in range(n):
arr.append(random.randint(1, 1000))
for _ in range(n//3):
arr.delete(random.randint(0, n//2))

expected_arr = [102, 134, 228, 247, 362, 373, 448,
480, 548, 686, 688, 696, 779]
assert counting_sort(arr)._data == expected_arr

def test_matrix_multiply_parallel():
ODA = OneDimensionalArray

Expand Down

0 comments on commit 7e3a3cd

Please sign in to comment.