C# 以创建可枚举项和使用降序排序所有内容的成本为代价。我说可以,就像源不是内存中的列表而是可查询的一样。我在第三个块中没有看到可为null的int技巧。尽管现在这似乎不是一个高性能的解决方案,因为它首先创建列表的一个副本,然后在LINQ表达式中生成一个可枚举项

C# 以创建可枚举项和使用降序排序所有内容的成本为代价。我说可以,就像源不是内存中的列表而是可查询的一样。我在第三个块中没有看到可为null的int技巧。尽管现在这似乎不是一个高性能的解决方案,因为它首先创建列表的一个副本,然后在LINQ表达式中生成一个可枚举项,c#,list,linq,sorting,C#,List,Linq,Sorting,以创建可枚举项和使用降序排序所有内容的成本为代价。我说可以,就像源不是内存中的列表而是可查询的一样。我在第三个块中没有看到可为null的int技巧。尽管现在这似乎不是一个高性能的解决方案,因为它首先创建列表的一个副本,然后在LINQ表达式中生成一个可枚举项。您可以在一行中将其ram在一起。然而,这种转换将更加微妙。此答案不包括性能调整,因为它不是问题的一部分。请参阅我发布的两个答案,其中涵盖了列表本身为null或其上的元素少于5个时的情况。这是一个非常好的大型数据集解决方案,非常感谢您的贡献+1


以创建可枚举项和使用降序排序所有内容的成本为代价。我说可以,就像源不是内存中的列表而是可查询的一样。我在第三个块中没有看到可为null的int技巧。尽管现在这似乎不是一个高性能的解决方案,因为它首先创建列表的一个副本,然后在LINQ表达式中生成一个可枚举项。您可以在一行中将其ram在一起。然而,这种转换将更加微妙。此答案不包括性能调整,因为它不是问题的一部分。请参阅我发布的两个答案,其中涵盖了列表本身为
null
或其上的元素少于5个时的情况。这是一个非常好的大型数据集解决方案,非常感谢您的贡献+1。需要澄清的一个问题是:该算法是否会对列表进行排序,直到找到第k个排序元素,然后退出?@sɐunıןqɐp是的,实际上是这样的(因此通常会显著减少工作量)。预期的复杂性是
O(n+k log k)
——但是,请注意,最坏的情况可能非常糟糕(我链接的维基百科文章中提到了这一点)。
List<int> list = new List<int>();

list.Add(2);
list.Add(18);
list.Add(21);
list.Add(10);
list.Add(20);
list.Add(80);
list.Add(23);
list.Add(81);
list.Add(27);
list.Add(85);
int fifth = list.OrderByDescending(x => x).Skip(4).First();
int result;
if(list != null && list.Count >= 5)
{
    list.Sort();
    result = list[list.Count - 5];
}
else // define behavior when list is null OR has less than 5 elements
List<int> copy = new List<int>(original);

List<int> copy = original.ToList();
int fifth;
try
{
    fifth = list.OrderByDescending(x => x).ElementAt(4);
}
catch (ArgumentOutOfRangeException)
{
    //Handle the exception
}
int fifth = list.OrderByDescending(x => x).ElementAtOrDefault(4);

if (fifth == 0)
{
    //handle default
}
var newList = list.Select(i => (int?)i).ToList();
int? fifth = newList.OrderByDescending(x => x).ElementAtOrDefault(4);

if (fifth == null)
{
    //handle default
}
int fifth = list?.Count >= 5 ?
    list.OrderByDescending(x => x).Take(5).Last() :
    throw new Exception("list is null OR has not enough elements");
int? fifth = list?.Count >= 5 ?
    list.OrderByDescending(x => x).Take(5).Last() :
    default(int?);

if(fifth == null) // define behavior
if(list == null || list.Count <= 0)
    throw new Exception("Unable to retrieve Nth biggest element");

int fifth = list.OrderByDescending(x => x).Take(5).Last();
public static class QuickHelpers
{
    // Put the code here
}
int resA = list.QuickSelect(2, (x, y) => Comparer<int>.Default.Compare(y, x));
int resB = list.QuickSelect(list.Count - 1 - 2);
public static IList<T> PartialSort<T>(IList<T> data, int k) where T : IComparable<T>
{
    int start = 0;
    int end = data.Count - 1;

    while (end > start)
    {
        var index = partition(data, start, end);
        var rank = index + 1;

        if (rank >= k)
        {
            end = index - 1;
        }
        else if ((index - start) > (end - index))
        {
            quickSort(data, index + 1, end);
            end = index - 1;
        }
        else
        {
            quickSort(data, start, index - 1);
            start = index + 1;
        }
    }

    return data;
}

static int partition<T>(IList<T> lst, int start, int end) where T : IComparable<T>
{
    T x = lst[start];
    int i = start;

    for (int j = start + 1; j <= end; j++)
    {
        if (lst[j].CompareTo(x) < 0) // Or "> 0" to reverse sort order.
        {
            i = i + 1;
            swap(lst, i, j);
        }
    }

    swap(lst, start, i);
    return i;
}

static void swap<T>(IList<T> lst, int p, int q)
{
    T temp = lst[p];
    lst[p] = lst[q];
    lst[q] = temp;
}

static void quickSort<T>(IList<T> lst, int start, int end) where T : IComparable<T>
{
    if (start >= end)
        return;

    int index = partition(lst, start, end);
    quickSort(lst, start, index - 1);
    quickSort(lst, index + 1, end);
}
PartialSort(list, 5);
Console.WriteLine(list[4]);