Die meisten effizienten Algorithmus für die Zusammenführung sortiert IEnumerable<T>

Habe ich mehrere riesige sortiert enumerable-Sequenzen, die ich Zusammenführen möchten. Diese Listen manipuliert, weil IEnumerable aber bereits sortiert. Da die input-Listen sortiert sind, sollte es möglich sein, mischen Sie Sie in einer Tour, ohne neu zu Sortieren alles.

Möchte ich halten, die zeitlich verzögert die Ausführung Verhalten.

Ich zu schreiben versucht, ein naiver Algorithmus, die das tun (siehe unten). Allerdings sieht es ziemlich hässlich und ich bin mir sicher, dass es optimiert werden kann. Es kann existieren eine mehr Akademische Algorithmus...

IEnumerable<T> MergeOrderedLists<T, TOrder>(IEnumerable<IEnumerable<T>> orderedlists, 
                                            Func<T, TOrder> orderBy)
{
    var enumerators = orderedlists.ToDictionary(l => l.GetEnumerator(), l => default(T));
    IEnumerator<T> tag = null;

    var firstRun = true;
    while (true)
    {
        var toRemove = new List<IEnumerator<T>>();
        var toAdd = new List<KeyValuePair<IEnumerator<T>, T>>();
        foreach (var pair in enumerators.Where(pair => firstRun || tag == pair.Key))
        {
            if (pair.Key.MoveNext())
                toAdd.Add(pair);
            else
                toRemove.Add(pair.Key);
        }

        foreach (var enumerator in toRemove)
            enumerators.Remove(enumerator);

        foreach (var pair in toAdd)
            enumerators[pair.Key] = pair.Key.Current;

        if (enumerators.Count == 0)
            yield break;

        var min = enumerators.OrderBy(t => orderBy(t.Value)).FirstOrDefault();
        tag = min.Key;
        yield return min.Value;

        firstRun = false;
    }
}

Die Methode kann verwendet werden, wie:

//Person lists are already sorted by age
MergeOrderedLists(orderedList, p => p.Age);

vorausgesetzt, die folgenden Person Klasse existiert irgendwo:

    public class Person
    {
        public int Age { get; set; }
    }

Duplikate sollten konserviert werden, wir kümmern uns nicht um Ihre Reihenfolge in der Sequenz. Sehen Sie offensichtliche Optimierung, die ich verwenden könnte?

InformationsquelleAutor franck | 2010-05-04
Schreibe einen Kommentar