{"id":23532455,"url":"https://github.com/hackware1993/chensort","last_synced_at":"2025-04-09T23:22:10.924Z","repository":{"id":39573406,"uuid":"499156854","full_name":"hackware1993/ChenSort","owner":"hackware1993","description":"The world's fastest general purpose sorting algorithm, 60% faster than Quicksort","archived":false,"fork":false,"pushed_at":"2024-12-07T07:49:40.000Z","size":31483,"stargazers_count":73,"open_issues_count":2,"forks_count":5,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-02T22:04:46.151Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hackware1993.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":"2022-06-02T13:56:53.000Z","updated_at":"2025-03-04T05:36:35.000Z","dependencies_parsed_at":"2025-01-16T11:09:13.281Z","dependency_job_id":"fdfbe3ac-5319-4ca9-aa87-b89657f5c2ef","html_url":"https://github.com/hackware1993/ChenSort","commit_stats":{"total_commits":30,"total_committers":1,"mean_commits":30.0,"dds":0.0,"last_synced_commit":"87bdd788734d4ad1913340a6d20faf915d2d0d67"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hackware1993%2FChenSort","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hackware1993%2FChenSort/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hackware1993%2FChenSort/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hackware1993%2FChenSort/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hackware1993","download_url":"https://codeload.github.com/hackware1993/ChenSort/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248126525,"owners_count":21051951,"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":[],"created_at":"2024-12-25T23:06:37.670Z","updated_at":"2025-04-09T23:22:10.901Z","avatar_url":"https://github.com/hackware1993.png","language":"C++","funding_links":["https://www.paypal.com/paypalme/hackware1993"],"categories":[],"sub_categories":[],"readme":"# ChenSort\n\nChenSort is an improved bucket sort, which is a general-purpose sorting algorithm.\n\n**The time complexity is O(n) at best and O(nlogn) at worst, the space complexity is O(n), and it is stable.**\n\nRandomly generate [1000,10000000] random numbers in the range [-2^63,2^63-1], average speed is 3 times faster than Quicksort, fastest is 20 times. Traditional bucket sort cannot handle such a large range of values, because the performance is much worse than quicksort due to the huge resource consumption.\n\n**All performance data is performed under a single thread, which can easily support multi-threading.**\n\n[Android APK demo, 6.05 MB](https://github.com/hackware1993/ChenSort/blob/master/ChenSort_Android.apk)\n\n[Windows exe demo, 5.8 MB](https://github.com/hackware1993/ChenSort/blob/master/ChenSort_Windows.7z)\n\nThe demos are all built on Flutter.\n\nDart code:\n\n```dart\n/// The essence of Chen Sort is an improved bucket sort\nvoid chenSort(List\u003cint\u003e list) {\n  if (list.length \u003c 2) {\n    return;\n  }\n\n  int maxValue = list[0];\n  int minValue = maxValue;\n  for (final element in list.skip(1)) {\n    if (element \u003e maxValue) {\n      maxValue = element;\n    }\n    if (element \u003c minValue) {\n      minValue = element;\n    }\n  }\n\n  /// All elements are the same and do not need to be sorted.\n  if (maxValue == minValue) {\n    return;\n  }\n\n  /// Limit the maximum size of the bucket to ensure the performance of long list\n  /// sorting, which can be adjusted according to the actual situation.\n  ///\n  /// The essential difference between this and bucket sorting is that the size of\n  /// the bucket is only related to the length of the list, not the range of element values.\n  int bucketSize = min(list.length, 50000);\n  int maxBucketIndex = bucketSize - 1;\n\n  List\u003cList\u003cint\u003e?\u003e buckets = List.filled(bucketSize, null);\n  int slot;\n\n  /// Calculate the bucket in which the element is located based on the value of the element\n  /// and the maximum and minimum values.\n\n  /// Overflow detection\n  BigInt range = BigInt.from(maxValue) - BigInt.from(minValue);\n  if (BigInt.from(range.toInt()) == range) {\n    int range = maxValue - minValue;\n    double factor = maxBucketIndex / range;\n    for (final element in list) {\n      // slot = (((element - minValue) / range) * maxBucketIndex).toInt();\n      slot = ((element - minValue) * factor).toInt();\n      if (buckets[slot] == null) {\n        buckets[slot] = [];\n      }\n      buckets[slot]!.add(element);\n    }\n  } else {\n    /// Overflowed(positive minus negative)\n    int positiveRange = maxValue;\n    int negativeRange = -minValue;\n    int positiveStartBucketIndex = maxBucketIndex ~/ 2 + 1;\n    int positiveBucketLength = maxBucketIndex - positiveStartBucketIndex;\n    int negativeBucketLength = positiveStartBucketIndex - 1;\n    for (final element in list) {\n      if (element \u003c 0) {\n        slot = negativeBucketLength -\n            ((-element / negativeRange) * negativeBucketLength).toInt();\n      } else {\n        slot = positiveStartBucketIndex +\n            ((element / positiveRange) * positiveBucketLength).toInt();\n      }\n      if (buckets[slot] == null) {\n        buckets[slot] = [];\n      }\n      buckets[slot]!.add(element);\n    }\n  }\n\n  int compare(int left, int right) {\n    return left - right;\n  }\n\n  int index = 0;\n  for (final bucket in buckets) {\n    if (bucket != null) {\n      if (bucket.length \u003e 1) {\n        if (bucket.length \u003e= 1000) {\n          chenSort(bucket);\n        } else {\n          /// The sort method here represents the fastest comparison-type algorithm (Quick sort, Tim sort, etc.)\n          bucket.sort(compare);\n        }\n        for (final element in bucket) {\n          list[index++] = element;\n        }\n      } else {\n        list[index++] = bucket[0];\n      }\n    }\n  }\n}\n```\n\nJava code(Multi-thread. The code just shows that this algorithm can easily support multi-threaded sorting, and the actual performance data is performed under a single thread):\n\n```java\nstatic void chenSort(Integer[] list) {\n    int length = list.length;\n    if (length \u003c 2) {\n        return;\n    }\n\n    Integer maxValue = Integer.MIN_VALUE;\n    Integer minValue = Integer.MAX_VALUE;\n    for (Integer element : list) {\n        if (element \u003e maxValue) {\n            maxValue = element;\n        }\n        if (element \u003c minValue) {\n            minValue = element;\n        }\n    }\n\n    /// All elements are the same and do not need to be sorted.\n    if (maxValue.equals(minValue)) {\n        return;\n    }\n\n    /// Limit the maximum size of the bucket to ensure the performance of long list\n    /// sorting, which can be adjusted according to the actual situation.\n    ///\n    /// The essential difference between this and bucket sorting is that the size of\n    /// the bucket is only related to the length of the list, not the range of element values.\n    int bucketSize = Math.min(length, 50000);\n    int maxBucketIndex = bucketSize - 1;\n\n    ArrayList\u003cInteger\u003e[] buckets = new ArrayList[bucketSize];\n    int slot;\n\n    /// Calculate the bucket in which the element is located based on the value of the element\n    /// and the maximum and minimum values.\n\n    /// Overflow detection\n    BigInteger bigRange = BigInteger.valueOf(maxValue).subtract(BigInteger.valueOf(minValue));\n    if (BigInteger.valueOf(bigRange.intValue()).equals(bigRange)) {\n        double factor = maxBucketIndex * 1.0 / (maxValue - minValue);\n        for (Integer element : list) {\n            slot = (int) ((element - minValue) * factor);\n            if (buckets[slot] == null) {\n                buckets[slot] = new ArrayList\u003c\u003e();\n            }\n            buckets[slot].add(element);\n        }\n    } else {\n        /// Overflowed(positive minus negative)\n        double positiveRange = maxValue;\n        double negativeRange = -minValue;\n        int positiveStartBucketIndex = maxBucketIndex / 2 + 1;\n        int positiveBucketLength = maxBucketIndex - positiveStartBucketIndex;\n        int negativeBucketLength = positiveStartBucketIndex - 1;\n        Integer zero = 0;\n        for (Integer element : list) {\n            if (element \u003c zero) {\n                slot = negativeBucketLength - (int) ((-element / negativeRange) * negativeBucketLength);\n            } else {\n                slot = (int) (positiveStartBucketIndex + ((element / positiveRange) * positiveBucketLength));\n            }\n            if (buckets[slot] == null) {\n                buckets[slot] = new ArrayList\u003c\u003e();\n            }\n            buckets[slot].add(element);\n        }\n    }\n\n    Comparator\u003cInteger\u003e comparator = Comparator.comparingInt(left -\u003e left);\n\n    // Multi-thread sorting between buckets\n    CountDownLatch countDownLatch = new CountDownLatch(buckets.length);\n    for (ArrayList\u003cInteger\u003e bucket : buckets) {\n        if (bucket != null) {\n            if (bucket.size() \u003e 1) {\n                executor.execute(() -\u003e {\n                    bucket.sort(comparator);\n                    countDownLatch.countDown();\n                });\n            } else {\n                countDownLatch.countDown();\n            }\n        } else {\n            countDownLatch.countDown();\n        }\n    }\n    try {\n        countDownLatch.await();\n    } catch (InterruptedException ignored) {\n    }\n\n    int index = 0;\n    for (ArrayList\u003cInteger\u003e bucket : buckets) {\n        if (bucket != null) {\n            if (bucket.size() \u003e 1) {\n                for (Integer element : bucket) {\n                    list[index++] = element;\n                }\n            } else {\n                list[index++] = bucket.get(0);\n            }\n        }\n    }\n}\n```\n\nPerformance(10 million random numbers sorted, single thread):\n\n```java\nRandom random = new Random();\nInteger[] arr = new Integer[10000000];\nlong maxValue = Integer.MAX_VALUE;\nlong minValue = Integer.MIN_VALUE;\nlong range = maxValue - minValue + 1;\nfor (int i = 0; i \u003c arr.length; i++) {\n    arr[i] = (int) (minValue + random.nextLong(range));\n}\nInteger[] copy = new Integer[arr.length];\nSystem.arraycopy(arr, 0, copy, 0, arr.length);\nlong start = System.currentTimeMillis();\nchenSort(arr);\nlong chenSortTimeUsage = System.currentTimeMillis() - start;\nstart = System.currentTimeMillis();\nArrays.sort(copy);\nlong quickSortTimeUsage = System.currentTimeMillis() - start;\n```\n\n```java\nchen sort: 3384 ms, quick sort: 9366 ms, 63.869314541960286%(2.767730496453901x) faster\nchen sort: 3450 ms, quick sort: 7223 ms, 52.2359130555171%(2.093623188405797x) faster\nchen sort: 1693 ms, quick sort: 5000 ms, 66.14%(2.9533372711163617x) faster\nchen sort: 2306 ms, quick sort: 6267 ms, 63.204084889101644%(2.717692974848222x) faster\nchen sort: 2922 ms, quick sort: 10145 ms, 71.19763430261213%(3.471937029431896x) faster\nchen sort: 3285 ms, quick sort: 9211 ms, 64.33611985669309%(2.803957382039574x) faster\nchen sort: 2661 ms, quick sort: 9236 ms, 71.18882633174535%(3.4708756106726795x) faster\nchen sort: 2538 ms, quick sort: 6422 ms, 60.47960137028963%(2.530338849487786x) faster\nchen sort: 1749 ms, quick sort: 4928 ms, 64.50892857142857%(2.8176100628930816x) faster\nchen sort: 1775 ms, quick sort: 5254 ms, 66.21621621621621%(2.96x) faster\nchen sort: 1626 ms, quick sort: 5155 ms, 68.45780795344326%(3.1703567035670357x) faster\nchen sort: 2375 ms, quick sort: 4877 ms, 51.302029936436334%(2.0534736842105263x) faster\nchen sort: 1923 ms, quick sort: 5250 ms, 63.37142857142857%(2.730109204368175x) faster\nchen sort: 3028 ms, quick sort: 9237 ms, 67.21879398072967%(3.0505284015852046x) faster\nchen sort: 2692 ms, quick sort: 9030 ms, 70.18826135105205%(3.3543833580980684x) faster\n```\n\n[Blog](https://mp.weixin.qq.com/s/uGNQxpBohPmlgxsHrE4pFg)\n\n[XiSort](https://github.com/hackware1993/XiSort) The slowest sorting algorithm I've developed with the most efficient code execution in the world.\n\n# Support me\n\nIf it helps you a lot, consider sponsoring me a cup of milk tea, or giving a star. Your support is\nthe driving force for me to continue to maintain.\n\n[Paypal](https://www.paypal.com/paypalme/hackware1993)\n\n![sponsorship.webp](https://github.com/hackware1993/ChenSort/blob/master/sponsorship.webp?raw=true)\n\nThanks to the following netizens for their sponsorship.\n\n1. 小小鸟 2022.06.08\n2. 孟焱 2022.06.08\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhackware1993%2Fchensort","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhackware1993%2Fchensort","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhackware1993%2Fchensort/lists"}