我有一系列对象,每个对象的序列号从0到ushort.MaxValue(0-65535)。我的序列中最多有大约10 000个项目,因此不应该有任何重复项,并且这些项目主要是根据它们的加载方式进行排序。我只需要按顺序访问数据,我不需要它们在列表中,如果这可以帮助。它也是经常做的事情,所以它不能有太高的Big-O。
对此列表进行排序的最佳方法是什么?
示例序列可以是( 在此示例中, 假设序列号是单个字节并且包装在255处):
240 241 242 243 244 250 251 245 246 248 247 249 252 253 0 1 2 254 255 3 4 5 6
然后
正确的顺序240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 0 1 2 3 4 5 6
我有一些不同的方法,包括制作一个ushort.MaxValue数组,只是增加位置,但这似乎是一种非常低效的方式,当我收到的数据有一个跳跃序列时我遇到了一些问题。但是,它的性能是O(1)..
另一种方法是正常订购商品,然后找到拆分(6-240),并将第一个商品移到最后。但我不确定这是不是一个好主意。
我的第三个想法是循环序列,直到找到错误的序列号,向前看直到找到正确的序列号,并将其移动到正确的位置。但是,如果早期的序列号错误,这可能会非常慢。
答案 0 :(得分:1)
这是你在找什么?
var groups = ints.GroupBy(x => x < 255 / 2)
.OrderByDescending(list => list.ElementAt(0))
.Select(x => x.OrderBy(u => u))
.SelectMany(i => i).ToList();
示例强> 在:
int[] ints = new int[] { 88, 89, 90, 91, 92, 0, 1, 2, 3, 92, 93, 94, 95, 96, 97, 4, 5, 6, 7, 8, 99, 100, 9, 10, 11, 12, 13 };
输出:
88 89 90 91 92 92 93 94 95 96 97 99 100 0 1 2 3 4 5 6 7 8 9 10 11 12 13
答案 1 :(得分:1)
我意识到这是一个老问题字节,我也需要这样做,并希望得到答案......
将SortedSet<FileData>
与自定义比较器一起使用;
其中FileData
包含有关您正在使用的文件的信息
e.g。
struct FileData
{
public ushort SequenceNumber;
...
}
internal class Sequencer : IComparer<FileData>
{
public int Compare(FileData x, FileData y)
{
ushort comparer = (ushort)(x.SequenceNumber - y.SequenceNumber);
if (comparer == 0) return 0;
if (comparer < ushort.MaxValue / 2) return 1;
return -1;
}
}
当您从磁盘读取文件信息时,请将它们添加到SortedSet
当您从SortedSet
中读出它们时,它们现在的顺序正确
请注意SortedSet
内部使用红黑色,这样可以在性能和内存之间取得很好的平衡
插入是O(log n)
遍历是O(n)