|
30 | 30 | 'jump_search',
|
31 | 31 | 'selection_sort',
|
32 | 32 | 'insertion_sort',
|
33 |
| - 'intro_sort' |
| 33 | + 'intro_sort', |
| 34 | + 'shell_sort', |
| 35 | + 'radix_sort' |
34 | 36 | ]
|
35 | 37 |
|
36 | 38 | def _merge(array, sl, el, sr, er, end, comp):
|
@@ -1850,3 +1852,157 @@ def partition(array, lower, upper):
|
1850 | 1852 | intro_sort(array, start=p+1, end=upper, maxdepth=maxdepth-1, ins_threshold=ins_threshold)
|
1851 | 1853 |
|
1852 | 1854 | return array
|
| 1855 | + |
| 1856 | +def shell_sort(array, *args, **kwargs): |
| 1857 | + """ |
| 1858 | + Implements shell sort algorithm. |
| 1859 | +
|
| 1860 | + Parameters |
| 1861 | + ========== |
| 1862 | +
|
| 1863 | + array: Array |
| 1864 | + The array which is to be sorted. |
| 1865 | + start: int |
| 1866 | + The starting index of the portion |
| 1867 | + which is to be sorted. |
| 1868 | + Optional, by default 0 |
| 1869 | + end: int |
| 1870 | + The ending index of the portion which |
| 1871 | + is to be sorted. |
| 1872 | + Optional, by default the index |
| 1873 | + of the last position filled. |
| 1874 | + comp: lambda/function |
| 1875 | + The comparator which is to be used |
| 1876 | + for sorting. If the function returns |
| 1877 | + False then only swapping is performed. |
| 1878 | + Optional, by default, less than or |
| 1879 | + equal to is used for comparing two |
| 1880 | + values. |
| 1881 | + backend: pydatastructs.Backend |
| 1882 | + The backend to be used. |
| 1883 | + Optional, by default, the best available |
| 1884 | + backend is used. |
| 1885 | +
|
| 1886 | + Returns |
| 1887 | + ======= |
| 1888 | +
|
| 1889 | + output: Array |
| 1890 | + The sorted array. |
| 1891 | +
|
| 1892 | + Examples |
| 1893 | + ======== |
| 1894 | +
|
| 1895 | + >>> from pydatastructs.linear_data_structures.algorithms import OneDimensionalArray, shell_sort |
| 1896 | + >>> arr = OneDimensionalArray(int, [3, 2, 1]) |
| 1897 | + >>> out = shell_sort(arr) |
| 1898 | + >>> str(out) |
| 1899 | + '[1, 2, 3]' |
| 1900 | + >>> out = shell_sort(arr, comp=lambda u, v: u > v) |
| 1901 | + >>> str(out) |
| 1902 | + '[3, 2, 1]' |
| 1903 | +
|
| 1904 | + References |
| 1905 | + ========== |
| 1906 | +
|
| 1907 | + .. [1] https://en.wikipedia.org/wiki/Shellsort |
| 1908 | + """ |
| 1909 | + start = int(kwargs.get('start', 0)) |
| 1910 | + end = int(kwargs.get('end', len(array) - 1)) |
| 1911 | + comp = kwargs.get('comp', lambda u, v: u <= v) |
| 1912 | + |
| 1913 | + n = end - start + 1 |
| 1914 | + gap = n // 2 |
| 1915 | + while gap > 0: |
| 1916 | + for i in range(start + gap, end + 1): |
| 1917 | + temp = array[i] |
| 1918 | + j = i |
| 1919 | + while j >= start + gap and not _comp(array[j - gap], temp, comp): |
| 1920 | + array[j] = array[j - gap] |
| 1921 | + j -= gap |
| 1922 | + array[j] = temp |
| 1923 | + gap //= 2 |
| 1924 | + |
| 1925 | + if _check_type(array, (DynamicArray, _arrays.DynamicOneDimensionalArray)): |
| 1926 | + array._modify(True) |
| 1927 | + |
| 1928 | + return array |
| 1929 | + |
| 1930 | +def radix_sort(array, *args, **kwargs): |
| 1931 | + """ |
| 1932 | + Implements radix sort algorithm for non-negative integers. |
| 1933 | +
|
| 1934 | + Parameters |
| 1935 | + ========== |
| 1936 | +
|
| 1937 | + array: Array |
| 1938 | + The array which is to be sorted. Must contain non-negative integers. |
| 1939 | + start: int |
| 1940 | + The starting index of the portion |
| 1941 | + which is to be sorted. |
| 1942 | + Optional, by default 0 |
| 1943 | + end: int |
| 1944 | + The ending index of the portion which |
| 1945 | + is to be sorted. |
| 1946 | + Optional, by default the index |
| 1947 | + of the last position filled. |
| 1948 | + backend: pydatastructs.Backend |
| 1949 | + The backend to be used. |
| 1950 | + Optional, by default, the best available |
| 1951 | + backend is used. |
| 1952 | +
|
| 1953 | + Returns |
| 1954 | + ======= |
| 1955 | +
|
| 1956 | + output: Array |
| 1957 | + The sorted array. |
| 1958 | +
|
| 1959 | + Examples |
| 1960 | + ======== |
| 1961 | +
|
| 1962 | + >>> from pydatastructs.linear_data_structures.algorithms import OneDimensionalArray, radix_sort |
| 1963 | + >>> arr = OneDimensionalArray(int, [170, 45, 75, 90, 802, 24, 2, 66]) |
| 1964 | + >>> out = radix_sort(arr) |
| 1965 | + >>> str(out) |
| 1966 | + '[2, 24, 45, 66, 75, 90, 170, 802]' |
| 1967 | +
|
| 1968 | + References |
| 1969 | + ========== |
| 1970 | +
|
| 1971 | + .. [1] https://en.wikipedia.org/wiki/Radix_sort |
| 1972 | + """ |
| 1973 | + start = int(kwargs.get('start', 0)) |
| 1974 | + end = int(kwargs.get('end', len(array) - 1)) |
| 1975 | + |
| 1976 | + n = end - start + 1 |
| 1977 | + max_val = array[start] |
| 1978 | + for i in range(start + 1, end + 1): |
| 1979 | + if array[i] is not None and array[i] > max_val: |
| 1980 | + max_val = array[i] |
| 1981 | + exp = 1 |
| 1982 | + while max_val // exp > 0: |
| 1983 | + count = [0] * 10 |
| 1984 | + output = [None] * n |
| 1985 | + |
| 1986 | + for i in range(start, end + 1): |
| 1987 | + if array[i] is not None: |
| 1988 | + digit = (array[i] // exp) % 10 |
| 1989 | + count[digit] += 1 |
| 1990 | + |
| 1991 | + for i in range(1, 10): |
| 1992 | + count[i] += count[i - 1] |
| 1993 | + |
| 1994 | + for i in range(end, start - 1, -1): |
| 1995 | + if array[i] is not None: |
| 1996 | + digit = (array[i] // exp) % 10 |
| 1997 | + count[digit] -= 1 |
| 1998 | + output[count[digit]] = array[i] |
| 1999 | + |
| 2000 | + for i in range(n): |
| 2001 | + array[start + i] = output[i] |
| 2002 | + |
| 2003 | + exp *= 10 |
| 2004 | + |
| 2005 | + if _check_type(array, (DynamicArray, _arrays.DynamicOneDimensionalArray)): |
| 2006 | + array._modify(True) |
| 2007 | + |
| 2008 | + return array |
0 commit comments