Представляя проблему, вы, похоже, характеризуете свои данные как массив пар 2*m
, но на самом деле они, по-видимому, структурированы как пара массивов 2*m
несвязанных элементов. То есть направленный край i
вашего графа представлен G->vecinos[0][i]
и G->vecinos[1][i]
(и есть другой направленный край, идущий в противоположном направлении), но эти два элемента не являются смежными в памяти. Они могут даже не быть рядом друг с другом.
Можно отсортировать это представление ребер, но не с помощью qsort
. Вам нужно написать свою собственную процедуру сортировки, которая объединяет отдельные массивы G->vecinos[0]
и G->vecinos[1]
.
Если бы это был я, я бы реструктурировал данные, поменяв местами измерения. Кроме того, я бы структурировал его для одного выделения - истинного динамически размещаемого двумерного массива, а не массива указателей. Это будет выглядеть примерно так:
// Structure definition
typedef struct some_key {
// ...
u32 (*vecinos)[2]; // a pointer to a 2-element array (the first of an array of such)
// ...
} Grafostv;
Grafostv* ConstruccionDelGrafo() {
Grafostv* G = (Grafostv*) malloc(sizeof(Grafostv));
// ... vecinos allocation
G->vecinos = malloc(2 * m * sizeof(*G->vecinos)); // just the one malloc() call
// ... vecinos assignments:
for (u32 i = 0; i < 2*m; i += 2) {
// ...
// note the inversion of index order:
G->vecinos[i][0] = v;
G->vecinos[i][1] = w;
G->vecinos[i+1][0] = w;
G->vecinos[i+1][1] = v;
}
// ... and that allows easier sorting, because each distinct logical unit
// (two u32 objects describing a directed graph edge) is stored as a single
// contiguous unit (a two-element array).
qsort(G->vecinos, 2 * m, sizeof(*G->vecinos), vecino_comp);
}
// ... where vecino_comp() looks like this:
int vecino_comp(const void *v1, const void *v2) {
const u32 (*vecino1)[2] = v1;
const u32 (*vecino2)[2] = v2;
if ((*vecino1)[0] < (*vecino2)[0]) {
return -1;
} else if ((*vecino1)[0] > (*vecino2)[0]) {
return 1;
} else if ((*vecino1)[1] < (*vecino2)[1]) {
return -1;
} else if ((*vecino1)[1] > (*vecino2)[1]) {
return 1;
} else {
return 0;
}
}
Ключевым понятием здесь, распространяющимся через пример, является указатель на массив. Таков тип указателя, к которому распадается многомерный массив, и он полностью и важно отличается от двойного указателя. Теперь это соответствует абстрактной идее массива ребер, потому что элементы массива верхнего уровня действительно соответствуют одному (направленному) ребру.