Сортировать по темам
У меня есть назначение, и мне нужен рабочий код. Прежде чем начать, я хочу понять проблему, но не могу понять, как ее написать.
У меня есть массив данных, например
var arr = new byte[] {5,3,1,7,8,5,3,2,6,7,9,3,2,4,2,1}
Мне нужно разделить этот массив пополам, выбросить его в пул потоков и делать это рекурсивно, пока у меня не будет элементов <=2. Если у меня есть 2 элемента, мне нужно проверить, что меньше, и поместить его в левую часть, а затем вернуть массив.
Что я не понимаю, как я могу объединить массив? я должен разделить массив, бросить поток в пул и заблокировать, пока он не будет готов? Как я могу получить результаты потока? Я собираюсь предположить, что невозможно объединить массивы без блокировки?
Вот что у меня так далеко.
static void Main(string[] args)
{
var arr = new byte[] { 5, 3, 1, 7, 8, 5, 3, 2, 6, 7, 9, 3, 2, 4, 2, 1 };
var newarr = Sort(arr);
Console.Write(BitConverter.ToString(newarr));
}
static byte[] Sort(byte[] arr)
{
if (arr.Length <= 2)
return arr;
if (arr.Length == 2)
{
if (arr[0] > arr[1])
{
var t = arr[0];
arr[0] = arr[1];
arr[1] = t;
}
return arr;
}
var arr1 = arr.Take(arr.Length / 2).ToArray();
var arr2 = arr.Skip(arr1.Count()).ToArray();
//??
return arr;
}
Примечание: профессор сказал, что мы можем попросить других о помощи. Я думаю, что могу решить это, не спрашивая, но я хочу получить лучший ответ. Потоки - моя слабость (я не делаю ничего другого, дБ, бинарный ввод, веб-интерфейс, просто не сложные потоки)
3 ответа
Это похоже на параллельную версию сортировки слиянием. Вы должны существенно заставить его работать как рекурсивная последовательная версия, но, очевидно, запускать каждую рекурсивную сортировку как отдельную задачу.
В вашем API задачи должен быть какой-то способ дождаться завершения и, возможно, также передать результаты. При этом вы можете достаточно хорошо скопировать традиционную сортировку слиянием: для каждой под-сортировки поместите задачу в пул и дождитесь завершения двух подзадач. Затем выполните объединение и передайте свой собственный результат в задачу по вызову.
Если у вас есть только обычный API потоков (т.е. нет реальной библиотеки задач), то я предлагаю вам предоставить выходные данные в третьем массиве: каждый поток будет иметь два входных массива и один выходной массив. Если вам разрешено создавать новые потоки для каждой задачи, вы можете дождаться завершения задачи, соединив две подпотоки.
Чтобы добавить к ответу Мартина, я бы не стал создавать меньшие копии массива. Вместо этого я хотел бы, чтобы каждый поток работал на подмножестве исходного массива.
Более чем рад обязательству: любая реализация многоядерной сортировки в.NET?