{"id":21536616,"url":"https://github.com/abdnh/counting-sort","last_synced_at":"2025-07-06T22:36:38.948Z","repository":{"id":105871315,"uuid":"397064239","full_name":"abdnh/counting-sort","owner":"abdnh","description":"A generic header-only implementation of counting sort in C","archived":false,"fork":false,"pushed_at":"2021-08-17T02:36:49.000Z","size":7,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-24T07:29:50.720Z","etag":null,"topics":["c","counting-sort","sorting-algorithms"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/abdnh.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-08-17T02:34:49.000Z","updated_at":"2021-08-17T02:54:13.000Z","dependencies_parsed_at":"2023-04-22T13:04:54.676Z","dependency_job_id":null,"html_url":"https://github.com/abdnh/counting-sort","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abdnh%2Fcounting-sort","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abdnh%2Fcounting-sort/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abdnh%2Fcounting-sort/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/abdnh%2Fcounting-sort/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/abdnh","download_url":"https://codeload.github.com/abdnh/counting-sort/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244104732,"owners_count":20398727,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c","counting-sort","sorting-algorithms"],"created_at":"2024-11-24T03:20:25.756Z","updated_at":"2025-03-17T20:27:09.102Z","avatar_url":"https://github.com/abdnh.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"\nA generic header-only implementation of [counting sort](https://en.wikipedia.org/wiki/Counting_sort) in C.\n\nCounting sort is a simple non-negative integer sorting algorithm suitable for small integers\nand is commonly used as a subroutine in [radix sort](https://en.wikipedia.org/wiki/Radix_sort).\nIt has linear running time thanks to the fact that it doesn't use comparisons.\nIt can be adapted to sort arbitrary objects as long as each object has some sort of an integer key.\n\nThe algorithm works by calculating the frequencies of each key and storing the counts in a `count` array.\nThen, for each key, it computes the the position in the sorted array where the objects with that key\nshould be placed with the help of the count array. Finally, it passes through the input array again\nand places each object in its sorted order in the output array according to the indices in the count array.\n\n## Usage\n\nThe header file `counting-sort.h` provides macros that you can use to generate\nfunctions for each data type you want to work with.\n\nThe macros are made generic by making them take a type parameter and a `GET_KEY(T array[], size_t i)`\ncallback that returns an unsigned integer (`size_t`) as a key for each element in the array.\n\nThere are two macros for generating functions: `DEF_COUNTING_SORT` and `DEF_COUNTING_SORT_M`.\n\n`DEF_COUNTING_SORT` generates a function that requires you to provide it with all the necessary memory buffers\nneeded by the counting sort algorithm, while `DEF_COUNTING_SORT_M` frees you from the hassle\nby dynamically allocating memory and freeing it after copying the sorted data to the array originally passed.\nTherefore, the two macros generate functions with different signatures.\n`DEF_COUNTING_SORT_M` is intended for one-off usage or when you don't care about memory usage or performance\nor just want the hassle-free way.\n\n## Example\n\nHere is a simplified example of using the library to sort the characters of a string lexicographically:\n\n```c\n#include \u003cstdio.h\u003e\n#include \u003cstdlib.h\u003e\n#include \u003cstring.h\u003e\n\n#include \"counting-sort.h\"\n\nsize_t get_key(char *str, size_t i) {\n    // the key is simply the character\n    return str[i];\n}\n\n// generate the sorting function\nDEF_COUNTING_SORT_M(char, sort_string, get_key)\n\nint main(void) {\n    char str[] = \"the quick brown fox jumps over the lazy dog\";\n    printf(\"before: '%s'\\n\", str);\n    sort_string(strlen(str), str);\n    printf(\"after: '%s'\\n\", str);\n\n    return 0;\n}\n```\n\nLet's work through the sorting processs step by step:\n1. We start by calculating the range of the keys in the input array to be able to allocate enough space for the\n  count array. We also find the smallest key to be used as an offset into the count array (`count[key - offset]`) to allow sorting\n  keys where the minimum key is not zero. For the input array in the above example (the string \"the quick brown fox jumps over the lazy dog\") we will get `offset = 32` and `range = 91`.\n2. We populate the count array with the frequency of each key. We get a count array like this:\n    ```\n    i:        0 1 2 ...  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79  80  81  82  83  84  85  86  87  88  89  90\n    count[i]: 8 0 0 ...   1   1   1   1   3   1   1   2   1   1   1   1   1   1   4   1   1   2   1   2   2   1   1   1   1   1\n    ```\n3. For each index `i` in the count array, we do the operation `count[i] += count[i - 1]` (if `i - 1` is in range).\n  After this, `count[i]` will hold the index right after where the last object with key `i + offset` will be in the sorted array. Our count array will become:\n    ```\n    i:        0 1 2 ...  65  66  67  68  69  70  71  72  73  74  75  76  77  78  79  80  81  82  83  84  85  86  87  88  89  90\n    count[i]: 8 8 8 ...   9  10  11  12  15  16  17  19  20  21  22  23  24  25  29  30  31  33  34  36  38  39  40  41  42  43\n    ```\n4. We now go over the input array again, but this time backwards (for [stability](https://en.wikipedia.org/wiki/Sorting_algorithm#Stability)),\n  get the key of each object, store the object in its new position in the sorted array using the count array,\n  then decrement its count value. In pseudocode as demonstrated in [Wikipedia](https://en.wikipedia.org/wiki/Counting_sort#Pseudocode):\n    ```\n    for i = length(input) - 1 downto 0 do\n        j = key(input[i])\n        count[j] -= 1\n        output[count[j]] = input[i]\n    ```\n5. We're done! We now have our sorted string:\n    ```\n    '        abcdeeefghhijklmnoooopqrrsttuuvwxyz'\n    ```\n\nAlso see [demo.c](demo.c) for an example that uses both of `DEF_COUNTING_SORT` and `DEF_COUNTING_SORT_M`.\n\n## References\n- [Counting Sort on Wikipedia](https://en.wikipedia.org/wiki/Counting_sort)\n- [A lecture on Coursera about counting sort by Robert Sedgewick](https://www.coursera.org/learn/algorithms-part2/lecture/2pi1Z/key-indexed-counting)\n- [Visualization of counting sort](https://www.cs.usfca.edu/~galles/visualization/CountingSort.html)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fabdnh%2Fcounting-sort","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fabdnh%2Fcounting-sort","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fabdnh%2Fcounting-sort/lists"}