我有几个类型为long(升序)的数字排序序列,并希望生成一个包含相同顺序的所有元素的主序列。我寻找最有效的排序算法来解决这个问题。我的目标是C#,。Net 4.0,因此也欢迎针对并行性的想法。
这是一个例子:
s1 = 1,2,3,5,7,13
s2 = 2,3,6
s3 = 4,5,6,7,8
得到的序列= 1,2,2,3,3,4,5,5,6,6,7,7,8,13
编辑:当有两个(或更多)相同的值时,那两个(或更多)的顺序无关紧要。
答案 0 :(得分:4)
只需合并序列。您无需再次对它们进行排序。
答案 1 :(得分:4)
我知道没有.NET Framework方法可以进行K-way合并。通常,它使用优先级队列(通常是堆)完成。这并不困难,而且效率很高。给定K个排序列表,一起保存N个项目,复杂度为O(N log K)。
我在文章A Generic Binary Heap Class中展示了一个简单的二进制堆类。在Sorting a Large Text File中,我将介绍多个已排序子文件的创建,并使用堆来执行K-way合并。考虑一小时(也许更少)的学习,你可以适应你的课程。
答案 2 :(得分:2)
您必须像合并排序一样合并序列。
这可以并行化:
这是合并功能:
int j = 0;
int k = 0;
for(int i = 0; i < size_merged_seq; i++)
{
if (j < size_seq1 && seq1[j] < seq2[k])
{
merged_seq[i] = seq1[j];
j++;
}
else
{
merged_seq[i] = seq2[k];
k++;
}
}
答案 3 :(得分:2)
简单的方法是逐个将它们相互合并。但是,这需要O(n*k^2)
时间,其中k
是序列数,n
是序列中的平均项数。但是,使用分而治之的方法可以将此时间降低到O(n * k * log k)。算法如下:
答案 4 :(得分:1)
更新:
事实证明,使用所有算法......简单的方法仍然更快:
private static List<T> MergeSorted<T>(IEnumerable<IEnumerable<T>> sortedBunches)
{
var list = sortedBunches.SelectMany(bunch => bunch).ToList();
list.Sort();
return list;
}
为了传统目的......
以下是优先排序的最终版本:
private static IEnumerable<T> MergeSorted<T>(IEnumerable<IEnumerable<T>> sortedInts) where T : IComparable<T>
{
var enumerators = new List<IEnumerator<T>>(sortedInts.Select(ints => ints.GetEnumerator()).Where(e => e.MoveNext()));
enumerators.Sort((e1, e2) => e1.Current.CompareTo(e2.Current));
while (enumerators.Count > 1)
{
yield return enumerators[0].Current;
if (enumerators[0].MoveNext())
{
if (enumerators[0].Current.CompareTo(enumerators[1].Current) == 1)
{
var tmp = enumerators[0];
enumerators[0] = enumerators[1];
enumerators[1] = tmp;
}
}
else
{
enumerators.RemoveAt(0);
}
}
do
{
yield return enumerators[0].Current;
} while (enumerators[0].MoveNext());
}