Если вы хотите отсортировать структуры, вам все равно придется разбить их на сравнение числовых c типов. Имея это в виду, давайте возьмем ваш пример с точками:
struct tagPoint
{
int x;
int y;
};
typedef struct tagPoint Point;
Теперь давайте предположим, что у вас есть массив Point
, и вы хотите, чтобы он был отсортирован. Вы можете использовать два подхода:
1. Простая функция, которая сортирует массив:
Просто сделайте функцию для сортировки массива:
void SortPointArray(Point* Points, unsigned int n)
{
/* This will sort the points with priority on the x and then the y value in ascending order. */
for(unsigned int i = 0; i < n-1; i++)
for(unsigned int j = i+1; j < n; j++)
{
if (Points[i].x > Points[j].x)
{
Point aux = Points[i];
Points[i] = Points[j];
Points[j] = aux;
}
else if ((Points[i].x == Points[j].x) && (Points[i].y > Points[j].y))
{
Point aux = Points[i];
Points[i] = Points[j];
Points[j] = aux;
}
}
}
2. Оберните алгоритм в обобщенную функцию c и используйте обратные вызовы для каждого типа, который вы хотите отсортировать:
Это немного сложнее, но сэкономит вам время, если вы будете часто его использовать. Здесь эта функция использует тот же алгоритм, что и выше, но может сортировать любые типы.
void Sort(void* lpArray, unsigned int n, size_t cbSize, int (*Cmp)(void*, void*), void (*Swap)(void*, void*))
{
for(unsigned int i = 0; i < n-1; i++)
for(unsigned int j = i+1; j < n; j++)
/* Cast void* to char* to get rid of warning with pointer arithmetic... */
if ( Cmp( ((char*)lpArray) + i*cbSize, ((char*)lpArray) + j*cbSize) )
Swap( ((char*)lpArray) + i*cbSize, ((char*)lpArray) + j*cbSize );
}
Как видите, для нее требуется еще две функции, переданные в качестве параметров. Если вы хотите, чтобы эта функция Sort
знала, как сортировать массив Point
, вы должны определить функцию Comparrison
и функцию Swapping
и указать функции Sort
, чтобы использовать их.
Вот как я их реализовал:
/** This function return 1 if p1 should be swapped with p2. */
int ComparePoints(void* vp1, void* vp2)
{
Point *p1, *p2;
p1 = vp1;
p2 = vp2;
if (p1->x > p2->x)
return 1;
else if ((p1->x == p2->x) && (p1->y > p2->y))
return 1;
return 0;
}
/** This will swap 2 points. */
void SwapPoints(void* vp1, void* vp2)
{
Point p = *(Point*)vp1;
*(Point*)vp1 = *(Point*)vp2;
*(Point*)vp2 = p;
}
Как вы их используете?
Если вы хотите использовать только первую функцию SortPointArray
, этого достаточно:
int main()
{
Point Array[10];
/* Read the points. */
for(unsigned int i = 0; i < 10; i++)
scanf("%d %d", &Array[i].x, &Array[i].y);
SortPointArray(Array, 10);
/*Print the points.*/
for(unsigned int i = 0; i < 10; i++)
printf("%d %d\n", Array[i].x, Array[i].y);
return 0;
}
Но если вы хотите использовать функцию generi c Sort
(которую я рекомендую, только если у вас есть несколько типов, которые вы хотите отсортировать, например Point
s, Line
s et c) Вы должны определить два обратных вызова (ComparePoints
и SwapPoints
)
int main()
{
Point Array[10];
/* Read the points. */
for(unsigned int i = 0; i < 10; i++)
scanf("%d %d", &Array[i].x, &Array[i].y);
Sort(Array, 10, sizeof(Point), ComparePoints, SwapPoints);
/*Print the points.*/
for(unsigned int i = 0; i < 10; i++)
printf("%d %d\n", Array[i].x, Array[i].y);
return 0;
}