合并排序大小不是 2^n 的数组
Merge sorting an array with a size that is not 2^n
在我发现的每个合并排序示例中,算法都是在大小为 8 或 2 的其他幂的数组上演示的。这使得演示更容易,但没有解释如何在数组上使用它不同大小的。你应该如何拆分子数组?
我认为你对这个问题想得太多了。在合并排序的经典版本中,您会继续分解输入,直到您拥有单元素子集合(根据定义排序)——然后您开始将子集合合并回一起。将集合分解为单元素集合主要是分配 memory/creating 集合对象并在每个对象中插入一个元素的练习。
基本的合并排序功能实际上并没有做太多事情。我的合并排序的 Clojure(Lisp 变体)实现如下所示:
(defn merge-sort [compare-func col]
(merge-runs compare-func (find-runs-of-3 compare-func col)))
也就是说,将输入集合col
分解为三个元素的子集合并排序,然后将这三个元素子集合合并得到最终的输出。如果输入集合不是三个元素的精确倍数,那没关系 - 这只是意味着将有一个 "leftover" 1 或 2 个元素的子集合与所有其他元素 sorted/merged .
(关于 "why collections-of-three" - 效率。首先,将要分类的集合分解为 collections-of-1 比分解为 collections-of-3 需要多三倍的努力。然后,也是,您可以使用平均 2.66 次比较而不是 3 次比较对三元素集合进行排序,这为每个子集合节省了 1/3 的比较。可能不会节省太多,直到您对 50K 的集合进行排序元素 :-).
祝你好运。
在我发现的每个合并排序示例中,算法都是在大小为 8 或 2 的其他幂的数组上演示的。这使得演示更容易,但没有解释如何在数组上使用它不同大小的。你应该如何拆分子数组?
我认为你对这个问题想得太多了。在合并排序的经典版本中,您会继续分解输入,直到您拥有单元素子集合(根据定义排序)——然后您开始将子集合合并回一起。将集合分解为单元素集合主要是分配 memory/creating 集合对象并在每个对象中插入一个元素的练习。
基本的合并排序功能实际上并没有做太多事情。我的合并排序的 Clojure(Lisp 变体)实现如下所示:
(defn merge-sort [compare-func col]
(merge-runs compare-func (find-runs-of-3 compare-func col)))
也就是说,将输入集合col
分解为三个元素的子集合并排序,然后将这三个元素子集合合并得到最终的输出。如果输入集合不是三个元素的精确倍数,那没关系 - 这只是意味着将有一个 "leftover" 1 或 2 个元素的子集合与所有其他元素 sorted/merged .
(关于 "why collections-of-three" - 效率。首先,将要分类的集合分解为 collections-of-1 比分解为 collections-of-3 需要多三倍的努力。然后,也是,您可以使用平均 2.66 次比较而不是 3 次比较对三元素集合进行排序,这为每个子集合节省了 1/3 的比较。可能不会节省太多,直到您对 50K 的集合进行排序元素 :-).
祝你好运。