【发布时间】:2016-01-20 19:50:06
【问题描述】:
我正在观看有关合并排序的 Coursera Princeton 算法讲座,我了解所有分析,除了合并最多 6 n log n 数组访问。
为什么是 6?
【问题讨论】:
-
6 非常依赖于实现,我想说。
标签: algorithm sorting mergesort array-algorithms
我正在观看有关合并排序的 Coursera Princeton 算法讲座,我了解所有分析,除了合并最多 6 n log n 数组访问。
为什么是 6?
【问题讨论】:
标签: algorithm sorting mergesort array-algorithms
我也想知道 6。我看了 Tim Roughgarden 的分析(视频 '1 - 7 - Merge Sort- Analysis (9 min).mp4'),他也说了 6。每个解释都感觉像是在挥手,但可能是因为太简单了,他们没有意识到需要解释:
复制到辅助数组时,每个 n(或 k)访问一个数组两次
aux[k] = a[k];
然后,在最坏的情况下,您永远不会耗尽子数组(您只比较常量),这样您就有了四个数组访问
else if (less(aux[j], aux[i])) a[k] = aux[j++]; (例如,如果输入顺序相反)或每次比较失败并且 else 在比较后开始(正确顺序),或两者的某种组合。没关系,只是根据最坏情况的定义,您无法通过常量(使用if (i > mid) 或else (j > hi))转义数组访问,因此每个k 都有四个。总共是 6 个。
(每一行代码都是 Sedgewick 的 - 他的文本的第 p271 页。)
【讨论】:
要获得 6 次数组访问,一个有点低效的合并过程:
read - read an element from even run for compare
read - read an element from odd run for compare
- compare
read - read the lower element again for copy
write - write the lower element to the output array for copy
... - after merge copy back
read - read element from output array to copy back
write - write element back to original array to copy back
正常情况是每移动一个元素就读一次写,但是考虑到元素太大而无法放入变量中的情况,比如字符串,所以在比较之后,必须读取要移动的字符串再次。
通常可以避免回写操作,具体取决于合并排序的编码方式。
【讨论】: