bsort: A theoretically efficient non-comparison-based sorting algorithm for integer and floating-point numbers

本文提出了一种名为 bsort 的非比较排序算法,该算法通过统一处理有符号/无符号整数及浮点数,实现了 O(wn)O(wn) 的时间复杂度和 O(w)O(w) 的辅助空间复杂度,在小字长数据场景下性能可与主流库中的优化混合算法相媲美。

Benjamín Guzmán

发布于 Wed, 11 Ma
📖 1 分钟阅读☕ 轻松阅读

Each language version is independently generated for its own context, not a direct translation.

这篇论文介绍了一种名为 bsort 的新排序算法。为了让你轻松理解,我们可以把“排序”想象成整理一堆杂乱无章的书籍,而 bsort 则是一位拥有“透视眼”和“魔法剪刀”的图书管理员。

1. 核心问题:传统的排序太慢了?

在计算机科学里,给一堆数字(比如 1, 5, 2, 9)排好顺序是基础操作。

  • 传统方法(比较排序):就像你手里拿着两本书,一本一本比大小,“这本书比那本大吗?是的,放后面”。这种方法有个物理极限,书越多,比得越累,时间复杂度是 O(nlogn)O(n \log n)
  • 非比较方法(如 bsort):这位管理员不看整本书的大小,而是直接看书脊上的条形码(二进制位)。他不需要两两比较,而是直接根据条形码的每一位把书分到不同的架子上。

2. bsort 是怎么工作的?(魔法剪刀的故事)

想象你有一堆混合了正数、负数小数(浮点数)的卡片。bsort 的工作流程就像是一个层层剥洋葱的过程:

第一步:处理“正负”的误会(符号位)

  • 问题:在计算机眼里,负数(比如 -5)的二进制开头是 1,正数(比如 5)开头是 0。如果直接按二进制大小排,1 开头的负数会被误以为比 0 开头的正数“大”,导致负数跑到了正数后面。
  • bsort 的妙招:它先拿一把“反向剪刀”,专门针对第一刀(最高位)。如果是升序排列,它故意把 1(负数)放在前面,把 0(正数)放在后面。这就好比先把所有“坏孩子”(负数)和“好孩子”(正数)分开,并纠正了顺序。

第二步:处理小数的“身份”(浮点数)

浮点数(如 3.14)在计算机里由三部分组成:符号(正负)、指数(大小级别,比如是 10 的几次方)、尾数(具体数值)。

  • bsort 的策略:它像剥洋葱一样,分三步走:
    1. 先分正负:把负数和正数彻底分开。
    2. 再分大小级别(指数):在正数堆里,把“大数”(指数大)和“小数”(指数小)分开;在负数堆里,因为负数越大绝对值越小,所以顺序要反过来排。
    3. 最后分细节(尾数):当符号和级别都确定后,剩下的就是比具体的数字大小了,这时候直接按二进制排就行。

第三步:递归切割

它不是一次性排好,而是像切蛋糕一样:

  1. 先看第 1 位,把数组切成两半。
  2. 再对这两半分别看第 2 位,再切。
  3. 一直切到最后一位。
    这就好比你要整理 100 本书,先按“是否红色封面”分成两堆,再在每一堆里按“是否有书名”分,再按“作者姓氏首字母”分……直到每堆只剩一本书。

3. 它的优缺点是什么?

优点:理论上的“闪电侠”

  • 速度极快(理论上):对于小数字(比如 8 位的字符,或者 16 位的短整数),bsort 快得惊人。因为它不需要两两比较,而是直接“按位”分发。如果数字很小,它就像坐火箭一样,O(n)O(n) 的时间复杂度意味着书越多,它越能发挥优势。
  • 省内存:它不需要额外的仓库(辅助空间),直接在原数组上操作,就像在原地整理书架,不占地方。

缺点:现实中的“笨重”

虽然理论很完美,但在实际测试中,bsort 处理大数字(如 64 位整数或双精度浮点数)时,并没有比现有的顶级算法(如 C++ 的 std::sort)快多少,甚至有时更慢。为什么?

  • 比喻:过度热情的图书管理员
    • 分支预测失败:bsort 在切分数据时,经常需要判断“这一位是 0 还是 1"。如果数据是随机的,就像让管理员猜硬币正反面,猜错率高达 50%。现代 CPU 很聪明,喜欢猜对,猜错了就要“清空流水线”(就像管理员走神了,得重新整理),这浪费了时间。
    • 递归太深:bsort 必须把 64 位数字切 64 次。这就像为了找一本书,管理员要上下楼梯 64 次。而传统的混合算法(如 Introsort)很聪明,切几刀发现书不多了,就改用“直接搬”的简单方法,不再死磕楼梯。
    • 缓存不友好:因为要反复扫描整个数组的每一位,数据在 CPU 的高速缓存(L1 Cache)里进进出出,导致 CPU 经常“找不到书”,得去慢速内存里取,效率降低。

4. 总结:它适合谁?

  • 适合场景:如果你要排序的是小数字(比如 8 位或 16 位的整数),或者数据量特别巨大且对内存极其敏感,bsort 是一个非常有潜力的选择。
  • 不适合场景:如果你要排序的是普通的 64 位大整数或复杂的浮点数,目前成熟的“混合算法”(结合了快速排序、堆排序等优势的算法)因为更懂 CPU 的脾气(利用缓存、减少递归),表现反而更好。

一句话总结
bsort 是一个理论完美、操作极简的排序算法,它通过“按位切割”的方式,在小数字领域展现了惊人的速度。但在处理大数字时,它因为过于“死板”和“频繁上下楼”(递归),输给了更懂得“见风使舵”(混合策略)的现代算法。作者认为,如果未来能给 bsort 加上一些“智能切换”的机制,它可能会成为真正的排序之王。