Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
421 views
in Technique[技术] by (71.8m points)

.net - In place sort for IList<T>?

Does .NET have an in place sort function for IList? I need to sort the collection itself, not create a new collection.

EDIT: The reason I need to do the sort in place is to avoid redrawing the UI unless something has actually changed. I don't want to create a hundred new custom controls if only one item is out of place.

EDIT: Again, this is a question about in place sorting, not just sorting in general.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

How about an in-place Quicksort / InsertionSort / ShellSort implementation:

public static class InPlaceQuickSort {
    private static void Swap<T>(IList<T> set, int left, int right) {
        T temp = set[left];
        set[left] = set[right];
        set[right] = temp;
    }

    private static Int32 Partition<T>(IList<T> set, int lBound, int rBound)
        where T : IComparable<T> {
        T pivot = set[rBound];
        int left = lBound - 1;
        int right = rBound;

        while (true) {

            while (set[++left].CompareTo(pivot) < 0) ;
            while (set[--right].CompareTo(pivot) > 0) if (left == right) break;

            if (left >= right) break;
            Swap(set, left, right);
        }

        Swap(set, left, rBound);
        return left;
    }

    private static IList<T> QuickSort<T>(IList<T> set, int lBound, int rBound)
        where T : IComparable<T> {
        if (lBound >= rBound) return set;

        Int32 pivot = Partition(set, lBound, rBound);
        QuickSort(set, lBound, pivot - 1);
        QuickSort(set, pivot + 1, rBound);

        return set;
    }

    public static IList<T> InsertionSort<T>(this IList<T> set)
        where T : IComparable<T> {
        for (Int32 index = 1; index < set.Count; index++) {
            for (Int32 insertion = index; insertion > 0 && set[insertion - 1].CompareTo(set[insertion]) > 0; insertion--) {
                Swap(set, insertion - 1, insertion);
            }
        }

        return set;
    }

    public static IList<T> ShellSort<T>(this IList<T> set)
        where T : IComparable<T> {
        Int32 shell = 1;

        while (shell < (set.Count / 3)) shell = shell * 3 + 1;

        while (shell >= 1) {
            for (Int32 index = shell; index < set.Count; index++) {
                for (Int32 insertion = index; insertion >= shell && set[insertion - shell].CompareTo(set[insertion]) > 0; insertion -= shell) {
                    Swap(set, insertion - shell, insertion);
                }
            }

            shell = shell / 3;
        }

        return set;
    }

    public static IList<T> QuickSort<T>(this IList<T> set)
        where T : IComparable<T> {
        return QuickSort<T>(set, 0, set.Count - 1);
    }
}

And, here's how you use it:

public static void Main() {
    List<Int32> numbers = new List<int> { 1, 3, 2, 4, 2 };

    foreach (Int32 number in numbers.QuickSort())
        Console.WriteLine(number);

    Console.ReadLine();
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...