|
30 | 30 | 'jump_search',
|
31 | 31 | 'selection_sort',
|
32 | 32 | 'insertion_sort',
|
33 |
| - 'intro_sort' |
| 33 | + 'intro_sort', |
| 34 | + 'radix_sort' |
34 | 35 | ]
|
35 | 36 |
|
36 | 37 | def _merge(array, sl, el, sr, er, end, comp):
|
@@ -1843,6 +1844,111 @@ def partition(array, lower, upper):
|
1843 | 1844 | elif maxdepth == 0:
|
1844 | 1845 | heapsort(array, start=lower, end=upper)
|
1845 | 1846 | return array
|
| 1847 | + |
| 1848 | +def radix_sort(array: Array, **kwargs) -> Array: |
| 1849 | + """ |
| 1850 | + Performs radix sort on the given array of non-negative integers. |
| 1851 | + Uses counting sort as a subroutine to sort by each digit position. |
| 1852 | +
|
| 1853 | + Parameters |
| 1854 | + ========== |
| 1855 | +
|
| 1856 | + array: Array |
| 1857 | + The array which is to be sorted. Must contain only non-negative integers. |
| 1858 | + start: int |
| 1859 | + The starting index of the portion |
| 1860 | + which is to be sorted. |
| 1861 | + Optional, by default 0 |
| 1862 | + end: int |
| 1863 | + The ending index of the portion which |
| 1864 | + is to be sorted. |
| 1865 | + Optional, by default the index |
| 1866 | + of the last position filled. |
| 1867 | + backend: pydatastructs.Backend |
| 1868 | + The backend to be used. |
| 1869 | + Optional, by default, the best available |
| 1870 | + backend is used. |
| 1871 | +
|
| 1872 | + Returns |
| 1873 | + ======= |
| 1874 | +
|
| 1875 | + output: Array |
| 1876 | + The sorted array. |
| 1877 | +
|
| 1878 | + Examples |
| 1879 | + ======== |
| 1880 | +
|
| 1881 | + >>> from pydatastructs import OneDimensionalArray, radix_sort |
| 1882 | + >>> arr = OneDimensionalArray(int,[170, 45, 75, 90, 802, 24, 2, 66]) |
| 1883 | + >>> out = radix_sort(arr) |
| 1884 | + >>> str(out) |
| 1885 | + '[2, 24, 45, 66, 75, 90, 170, 802]' |
| 1886 | +
|
| 1887 | + References |
| 1888 | + ========== |
| 1889 | +
|
| 1890 | + .. [1] https://en.wikipedia.org/wiki/Radix_sort |
| 1891 | +
|
| 1892 | + Note |
| 1893 | + ==== |
| 1894 | +
|
| 1895 | + This implementation: |
| 1896 | + 1. Only works with non-negative integers |
| 1897 | + 2. Uses LSD (Least Significant Digit) radix sort |
| 1898 | + 3. Uses base-10 digits |
| 1899 | + """ |
| 1900 | + raise_if_backend_is_not_python( |
| 1901 | + radix_sort, kwargs.get('backend', Backend.PYTHON)) |
| 1902 | + |
| 1903 | + # Find maximum number to know number of digits |
| 1904 | + max_val = 0 |
| 1905 | + start = kwargs.get('start', 0) |
| 1906 | + end = kwargs.get('end', len(array) - 1) |
| 1907 | + |
| 1908 | + for i in range(start, end + 1): |
| 1909 | + if array[i] is not None and array[i] > max_val: |
| 1910 | + max_val = array[i] |
| 1911 | + |
| 1912 | + # Do counting sort for every digit |
| 1913 | + exp = 1 |
| 1914 | + while max_val // exp > 0: |
| 1915 | + # Create output array with same type as input |
| 1916 | + output = type(array)(array._dtype, [array[i] for i in range(len(array))]) |
| 1917 | + if _check_type(output, DynamicArray): |
| 1918 | + output._modify(force=True) |
| 1919 | + |
| 1920 | + # Store count of occurrences |
| 1921 | + count = [0] * 10 |
| 1922 | + |
| 1923 | + # Count occurrences of current digit |
| 1924 | + for i in range(start, end + 1): |
| 1925 | + if array[i] is not None: |
| 1926 | + idx = (array[i] // exp) % 10 |
| 1927 | + count[idx] += 1 |
| 1928 | + |
| 1929 | + # Change count[i] to position of digit in output |
| 1930 | + for i in range(1, 10): |
| 1931 | + count[i] += count[i - 1] |
| 1932 | + |
| 1933 | + # Build output array |
| 1934 | + i = end |
| 1935 | + while i >= start: |
| 1936 | + if array[i] is not None: |
| 1937 | + idx = (array[i] // exp) % 10 |
| 1938 | + output[start + count[idx] - 1] = array[i] |
| 1939 | + count[idx] -= 1 |
| 1940 | + i -= 1 |
| 1941 | + |
| 1942 | + # Copy output array to array |
| 1943 | + for i in range(start, end + 1): |
| 1944 | + array[i] = output[i] |
| 1945 | + |
| 1946 | + exp *= 10 |
| 1947 | + |
| 1948 | + if _check_type(array, (DynamicArray, _arrays.DynamicOneDimensionalArray)): |
| 1949 | + array._modify(True) |
| 1950 | + |
| 1951 | + return array |
1846 | 1952 | else:
|
1847 | 1953 | p = partition(array, lower, upper)
|
1848 | 1954 |
|
|
0 commit comments