Используется алгоритм Quicksort , который нестабилен при эффективной реализации (на месте).Это означает, что это не гарантирует, что равные значения сохранят свое прежнее относительное положение после сортировки.
Например, если у вас есть несколько точек:
Point[] points = new Point[]
{
new Point(0, 1),
new Point(0, 2),
new Point(0, 3),
new Point(1, 1),
new Point(1, 2),
new Point(1, 3)
};
И вы сортируете этиточки только по x-координате , используя этот компаратор:
private int CompareByX(Point a, Point b)
{
return a.X - b.X;
}
Это будет гарантировать только то, что точки отсортированы по их x-координате, то есть вы можете легко получить смешаннуюпорядок вверх (если смотреть на координату y):
Point(0, 3)
Point(0, 2)
Point(0, 1)
Point(1, 3)
Point(1, 2)
Point(1, 1)
[Edit]
Это не означает, что алгоритм сортировки недетерминирован (случайным образом).Для одинаковых входных данных вы будете получать одинаковые выходные данные при каждом запуске.Вы также можете предсказать фактическую реорганизацию, если точно изучите алгоритм, но это не нужно.Достаточно просто знать, что это происходит при использовании процедуры сортировки.
Вот рабочий пример вашей проблемы, попробуйте изменить размеры тестовых данных (первая строка в Main
) и посмотрите, как массив получаетреорганизован при каждом запуске:
class Program
{
static void Main()
{
Point[] points = CreateTestData(1, 4).ToArray();
DisplayItems("Before", points);
Array.Sort(points, CompareByX);
DisplayItems("After", points);
Console.ReadLine();
}
private class Point
{
public int X { get; private set; }
public int Y { get; private set; }
public override string ToString()
{ return string.Format("({0},{1})", X, Y); }
public Point(int x, int y)
{ X = x; Y = y; }
}
private static int CompareByX(Point a, Point b)
{ return a.X - b.X; }
private static IEnumerable<Point> CreateTestData(int maxX, int maxY)
{
for (int x = 0; x <= 1; x++)
for (int y = 0; y <= 4; y++)
yield return new Point(x, y);
}
private static void DisplayItems(string msg, Point[] points)
{
Console.WriteLine(msg);
foreach (Point p in points)
Console.WriteLine(p.ToString());
Console.WriteLine();
}
}
Конечно, если вы расширите делегат компаратора для включения координаты Y, у вас не будет этой проблемы:
private static int CompareByX(Point a, Point b)
{
if (a.X == b.X)
return a.Y - b.Y;
else
return a.X - b.X;
}