Самый простой способ сделать это - просто отсортировать данные и взять N элементов спереди.Это рекомендуемый способ для небольших наборов данных - в противном случае все более сложное просто не стоит этого.
Однако для больших наборов данных может быть намного быстрее сделать то, что известно как Partial Sort
.
Есть два основных способа сделать это: использовать кучу или использовать специальную быструю сортировку.
В статье, которую я связал, описывается, как использовать кучу.Ниже я приведу частичную сортировку:
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);
}
Затем, чтобы получить доступ к 5-му по величине элементу в списке, вы можете сделать это:
PartialSort(list, 5);
Console.WriteLine(list[4]);
Для больших наборов данных частичная сортировка можетбыть значительно быстрее, чем полная сортировка.
Приложение
См. здесь для другого (возможно, лучшего) решения, использующего Алгоритм быстрого выбора .