排序O(n), 2022-06-15

(2022.06.15 Wed)
基于divide-and-conquer范式的快速排序、递归排序都达到了基于比较法排序的极限,复杂度达到,但在特定情况下,排序的复杂度仍然可以降低。这里我们考虑对k-v对数据的排序,其中的key的类型受限。

桶排序 bucket sort

(2022.06.16 Thur)
考虑一个序列,有个元素,每个元素都是k-v对,keys的范围在之间,,需要对根据keys排序。这种特定情况下可以达到的排序时间。换句话说,如果是,则对排序的时间可以达到。这个排序问题的关键问题在于序列中元素的限定条件可以避免使用比较排序。

对这样的序列做排序,采用桶排序bucket-sort。与快速排序并归排序不同,桶排序不是基于比较,而使用keys作为一个桶序列bucket array 的索引,该桶序列元素(cell)的索引范围是0到。中对应key为的元素被放置在,而本身也可以是个序列。当把中的元素完全插入到中,可以从中按序取元素存入到中,即,实现对的排序。

桶排序的时间和空间复杂度都是,因此在时,桶排序很高效,比如或时。当然随着增大到与相差不多,排序算法性能下降。

桶排序的一个重要特征是当有keys有大量重复时,依然可以得出正确结果,而且能够保证排序结果的稳定。

根排序 radix sort

稳定排序的重要性之一在于它允许桶排序法应用于整数排序以外的更普遍的情况。比如我们对输入排序,每个元素的key是数值对,而非一个单独的数值key, ,。这种情况下可以使用字典排序,,当或。这种pairwise的字典排序可以应用于等长字符创或等长tuple的排序。

根排序算法针对元素为pair key的序列做排序,对序列使用两次稳定桶排序。两次分别作用于每个元素的第一、二个key,但先一后二和先二后一的效果还值得分析讨论。

我们从案例入手分析这个问题。考虑一个pair key的序列,这里我们只给出key的部分,不含value部分。
对key的第一个分量做排序,得到如下序列
对的第二个分量做稳定排序,得到
得到的结果并非有序序列。

另一方面,如果首先对中的第二个分量做稳定排序,得到
在对这个结果中的第一个分量做稳定排序,得到
这次的结果已经符合字典排序了。

对于三元或者更多元的测试作为练习。

根据这个实验可以得到如下定理

定义是长度为的k-v对序列,每个元素的key是,其中,可以应用根排序算法对该序列实现时间的字典排序。

根排序可以应用于key是复合结构的k-v序列的元素排序。比如针对订场的字符串的排序,其中每个字符都可以当做整数值。

Reference

1 Goodrich and etc., Data Structures and Algorithms in Python

你可能感兴趣的:(排序O(n), 2022-06-15)