Это просто небольшие изменения в функции comparizon, чтобы сделать библиотеку QSort стабильной. Смотрите ссылку here
что-то вроде ниже, должны сделать трюк (непроверенный, быть осторожным):
int comp_on_price(const void *a, const void *b)
{
if ((*(B *)a).price < (*(B *)b).price)
return 1;
else if ((*(B *)a).price > (*(B *)b).price)
return -1;
else
// if zero order by addresses
return a-b;
}
Это будет работать, если вы можете гарантировать и Ь в том же адресном пространстве (два указателя в том же массив) и что при каждом сравнении обеспечивается более полное упорядочение массива, адреса нижних структур будут становиться еще медленнее. Это справедливо для сортов пузырьков или подобных. Это также будет работать для тривиальной реализации QucikSort (чего нет qsort). Однако для других алгоритмов или любого алгоритма, использующего дополнительное адресное пространство для временного хранения (возможно, для оптимизации), это свойство не будет истинным.
Если вы сортируете какой-либо уникальный идентификатор в сравниваемых элементах (в текущем примере, который, вероятно, верен для идентификатора поля), другим способом сделать стабилизацию сортировки будет сравнение этих элементов. Вы также можете добавить такой уникальный ключ в новое поле для этой цели, но поскольку он использует больше памяти, вы должны рассмотреть третий вариант, описанный ниже, перед тем как это сделать.
Мой предпочтительный метод по-прежнему будет третьим, не сортируйте массив структур напрямую, а сортируйте массив указателей на фактические элементы структуры. Это имеет несколько хороших свойств. Сначала вы можете сравнить массивы указанной структуры, так как она не изменится, и она станет стабильной.
Функция сравнения будет что-то вроде:
int comp_on_price(const void *a, const void *b)
{
if ((*(B **)a)->price < (*(B **)b)->price)
return 1;
else if ((*(B **)a)->price > (*(B **)b)->price)
return -1;
else
// if zero, order by addresses
return *(B **)a-*(B **)b;
}
Других хороших свойств, что это избежать перемещения структур вокруг во время сортировки, это только нужно двигающиеся указателей, и это может быть экономия времени. Вы также можете хранить несколько таких массивов указателей и одновременно допускать несколько упорядоченных обращений к элементам массива.
Недостатки в том, что требуется некоторая память и доступ к элементам несколько медленнее (один уровень косвенности больше).
Вы не можете на самом деле _say_, что это O-ness, так как это не обязано быть quicksort :-) – paxdiablo
Я считаю, что qsort нестабилен, я могу ошибаться? – learner123
И вы можете сделать это быстрее (в среднем) –