如何有效地对可变大小的元素列表进行排序?

时间:2018-09-16 22:15:54

标签: sorting z80

我这样做的动机是编写一些Z80汇编代码来对TI-83 +系列的变量分配表(VAT)进行排序,但是作为一个普遍问题,我也对此感兴趣。

我要排序的增值税部分安排在连续内存中,每个元素都包含一些固定大小的数据,然后是名称的大小字节,然后是名称。使事情变得复杂的是,增值税的两侧有两个堆栈,没有提供任何摆动空间来安全地为其分配RAM。

理想情况下,我想使用O(1)空间,因为我已经可以访问2 768字节的非用户RAM缓冲区。我还想使其速度更快,因为它可以包含许多条目,并且这是一个6MHz的处理器(虽然实际上没有指令流水线,但实际上是1MIPS)。还必须注意,每个条目至少8个字节,最多15个字节。

我能够想到的最佳方法依赖于块内存传输,而Z80上的传输并不特别快。过去,其他人已经实现了插入排序算法,但是它并不是特别有效。同样,虽然我可以(并且已经)编写了代码以将其收集到一个数组中并对所有条目的指针进行排序,但它需要可变的空间量,因此我必须分配已经供不应求的用户RAM。 >

我觉得它隐约使我想起了我曾经遇到过的一些组合技巧,但是在我的生命中,对这个问题的好的解决方案使我回避了。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

将表划分为N个块,每个块足够小,可以使用固定大小的可用临时缓冲区按现有代码排序。然后对N个列表执行合并排序以产生最终结果。

代替N路合并,最简单的方法是使用2路合并将N件成对排序。

在对每个片段进行排序时,使用哈希码来避免字符串比较可能是一个优势。似乎像基数排序可能会提供一些好处。

对于复制数据,Z-80的块移动指令LDIRLDDR相当昂贵,但很难被击败。将LDIR展开为一系列LDI可以更快。将堆栈指针指向源和目标,并使用多个POP然后使用PUSH可以更快,但是需要禁用中断并保证不会发生不可屏蔽的中断。