簡體   English   中英

C#等價於C ++ std :: partial_sort嗎?

[英]Is there a C# equivalent to C++ std::partial_sort?

我正在嘗試通過許多標准為可排序的數據集實現分頁算法。 不幸的是,雖然其中一些標准可以在數據庫級別實現,但有些必須在應用程序級別完成(我們必須與另一個數據源集成)。 我們有一個分頁(實際上是無限滾動)的要求,並且正在尋找一種方法來最小化在每個分頁調用時在應用程序級別對整個數據集進行排序的痛苦。

進行部分排序的最佳方法是什么,只排序絕對需要排序的列表部分? 是否有相當於.NET庫中可用的C ++的std::partial_sort函數? 我該如何解決這個問題?

編輯:這是我想要的一個例子:

假設我需要根據一些排序標准獲得1000個元素集的元素21-40。 為了加快排序速度,因為我每次都必須遍歷整個數據集(這是一個基於HTTP的Web服務,這是無狀態的),我不需要整個數據集。 我只需要正確排序21-40元素。 創建3個分區就足夠了:元素1-20, 未排序 (但都小於元素21); 元素21-40, 排序 ; 和元素41-1000, 未排序 (但都大於元素40)。

好。 以下是我根據您在回復我的評論時所說的內容。

我想能夠說“第4到第6”並得到類似的東西:3,2,1(未分類,但都不到第4個元素); 4,5,6(排序並在同一個地方,它們將用於排序列表); 8,7,9(未分類,但都大於正確的第6個元素)。

讓我們在列表中添加10以使其更容易:10,9,8,7,6,5,4,3,2,1。

所以,你可以做的是使用快速選擇算法找到 i k 元素。 在你的情況下,我是4,k是6.那當然會返回值4和6.這將在你的列表中進行兩次傳遞。 所以,到目前為止,運行時間是O(2n)= O(n)。 當然,下一部分很簡單。 我們關注的數據有上下限。 我們需要做的就是再次通過我們的列表來查找我們的上限和下限之間的任何元素。 如果我們找到這樣一個元素,我們將它扔進一個新的List。 最后,我們對List進行排序,其中僅包含我們關心的 i k 元素。

所以,我相信總運行時最終為O(N)+ O((ki)lg(ki))

static void Main(string[] args) {
    //create an array of 10 million items that are randomly ordered
    var list = Enumerable.Range(1, 10000000).OrderBy(x => Guid.NewGuid()).ToList();

    var sw = Stopwatch.StartNew();
    var slowOrder = list.OrderBy(x => x).Skip(10).Take(10).ToList();
    sw.Stop();
    Console.WriteLine(sw.ElapsedMilliseconds);
    //Took ~8 seconds on my machine

    sw.Restart();
    var smallVal = Quickselect(list, 11);
    var largeVal = Quickselect(list, 20);
    var elements = list.Where(el => el >= smallVal && el <= largeVal).OrderBy(el => el);
    Console.WriteLine(sw.ElapsedMilliseconds);
    //Took ~1 second on my machine
}

public static T Quickselect<T>(IList<T> list , int k) where T : IComparable {
    Random rand = new Random();
    int r = rand.Next(0, list.Count);
    T pivot = list[r];
    List<T> smaller = new List<T>();
    List<T> larger = new List<T>();
    foreach (T element in list) {
        var comparison = element.CompareTo(pivot);
        if (comparison == -1) {
            smaller.Add(element);
        }
        else if (comparison == 1) {
            larger.Add(element);
        }
    }

    if (k <= smaller.Count) {
        return Quickselect(smaller, k);
    }
    else if (k > list.Count - larger.Count) {
        return Quickselect(larger, k - (list.Count - larger.Count));
    }
    else {
        return pivot;
    }
}

您可以使用List <T> .Sort(int,int,IComparer <T>)

inputList.Sort(startIndex, count, Comparer<T>.Default);

Array.Sort()有一個重載,它接受indexlength參數,允許您對數組的子集進行排序。 List也存在相同的情況。

當然,你無法直接對IEnumerable排序。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM