@Alexandru, весь смысл SO в том, чтобы быть местом для всех вопросов, связанных с программированием, любого уровня квалификации. Как вы думаете, куда Google должен направлять людей, когда они используют ваш запрос? Власти желают, чтобы это пришло сюда - когда SO является главной ссылкой Google для этого запроса, наша работа сделана.
paxdiablo
1
Мой исходный код был ленивым и, вероятно, сильно отличался от того, который вы бы нашли с помощью поиска Google. Однако после всего вклада сообщества у вас есть пример хорошей реализации того, как использовать qsort.
повтор
@paxdiablo: если это так, они могли бы просто разместить стандартную документацию lib - я сомневаюсь, что этот вопрос добавит что-либо выше этой канонической ссылки здесь. Возможно, для некоторых сложных случаев - но просто чтобы найти базовую функцию?
Eamon Nerbonne
4
Даже подобные вопросы способствуют окончательной полноте SO как полезной базы данных для застрявших кодеров.
littlegreen
7
Также во многих случаях люди не знают, что искать. Если вы знаете, что c имеет функцию сортировки с именем qsort (), документация легко доступна, однако если вы не знаете, что искать, какой ресурс следует использовать.
повтор
Ответы:
120
qsort()это функция, которую вы ищете. Вы вызываете его с помощью указателя на ваш массив данных, количества элементов в этом массиве, размера каждого элемента и функции сравнения.
Он творит свое волшебство, и ваш массив сортируется на месте. Пример ниже:
#include<stdio.h>#include<stdlib.h>int comp (constvoid* elem1,constvoid* elem2){int f =*((int*)elem1);int s =*((int*)elem2);if(f > s)return1;if(f < s)return-1;return0;}int main(int argc,char* argv[]){int x[]={4,5,2,3,1,0,9,8,6,7};
qsort (x,sizeof(x)/sizeof(*x),sizeof(*x), comp);for(int i =0; i <10; i++)
printf ("%d ", x[i]);return0;}
Вам действительно следует использовать sizeof (* x) на случай, если вы когда-нибудь измените тип в будущем, но +1 для предоставления образца.
paxdiablo
13
В общем случае попытка сравнить целые числа путем вычитания одного из другого приведет к переполнению. Лучше с самого начала отказаться от этой вредной привычки. Использованиеreturn (f > s) - (f < s);
AnT
4
Хорошо, изменено согласно большинству предложений. Я рисую черту, @ChrisL, когда мне нужен size_t, поскольку мои массивы никогда не становятся такими большими :-) И, @AndreyT, хотя этот хакер умный, я предпочитаю, чтобы мой код был читабельным :-)
paxdiablo
2
@paxdiablo: Это «хакерство» - устоявшаяся идиома. Любой достойный программист сразу узнает это. Это не оказывает негативного влияния на читаемость.
AnT
2
@JAamish Стандарт ISO C99 N1256, в «7.20.5.2 qsortФункция« Пункт 4 »Если два элемента сравниваются как равные, их порядок в результирующем отсортированном массиве не указан».
12431234123412341234123
61
Стандартная библиотека C / C ++ <stdlib.h>содержит qsortфункцию.
Это не лучшая реализация быстрой сортировки в мире, но она достаточно быстрая и ОЧЕНЬ ЛЕГКАЯ для использования ... формальный синтаксис qsort:
Единственное, что вам нужно реализовать, это функция compare_function, которая принимает два аргумента типа «const void», которые могут быть преобразованы в соответствующую структуру данных, а затем возвращать одно из этих трех значений:
отрицательный, если a должно быть перед b
0, если a равно b
положительный, если a должно быть после b
1. Сравнение списка целых чисел :
просто бросить а и Ь в целые числа , если это x < y, x-yимеет отрицательное значение , x == y, x-y = 0, x > y, x-yположительный
x-yярлык способ сделать это :) обратным , *x - *yчтобы *y - *xпри сортировке в уменьшении / обратный порядок
int compare_function(constvoid*a,constvoid*b){int*x =(int*) a;int*y =(int*) b;return*x -*y;}
2. Сравнение списка строк :
Для сравнения строк вам нужна strcmpфункция внутри <string.h>библиотеки.
strcmpпо умолчанию вернет -ve, 0, ve соответственно ... для сортировки в обратном порядке, просто измените знак, возвращаемый strcmp
Довольно хороший ответ, но объяснение возвращаемого значения функции сравнения обратное. Кроме того, в некоторых примерах используется трюк xy, который может давать неверные результаты (и менее очевиден, чем простое сравнение).
Адриан Маккарти
Что ж, что касается меня сейчас .. это работает для любого конкурса;)
whacko__Cracko
5
Уловка xy не работает, если разница между x и y больше, чем наибольшее представимое целое число. Так что это нормально при сравнении двух положительных чисел, но не удастся сравнить, например, INT_MAX и -10. Я проголосовал за, потому что мне нравятся все примеры сортировки самых разных типов.
Дуглас
2
Помимо проблемы переполнения как в целочисленном компараторе, так и в ключевых функциях компаратора, функция сравнения строк неверна. При сортировке массива intзначения, переданные в компаратор, int *замаскированы под void *. char *Таким образом, при сортировке массива значения, переданные в компаратор, char **замаскированы как void *. Таким образом, правильный код должен быть: int compare_function(const void *a,const void *b) { return (strcmp(*(char **)a, *(char **)b)); }.
Джонатан Леффлер,
1
Для целочисленных сравнений, устойчивых к переполнению, подумайте if (x > y) return +1; else if (x < y) return -1; else return 0;, или, если вам нужно простое выражение, тогда return (x > y) - (x < y);. Это всегда оценивает два сравнения на уровне C, но оптимизатор может этого избежать. Вычитание не работает для значений без знака. Первая версия хорошо работает, когда вы имеете дело с серией сравнений - сначала сравниваете 2 целочисленных члена структуры, и если они равны, то два двойных, затем две строки и т.д. в C, а также в Perl.
Джонатан Леффлер,
9
Конечно: qsort()это реализация сортировки (не обязательно быстрой сортировки, как следует из названия).
qsortне обязательно реализовывать с помощью Quicksort.
Джеймс МакНеллис,
6
Хотя он и не входит в стандартную библиотеку, https://github.com/swenson/sort имеет только два файла заголовков, которые вы можете включить, чтобы получить доступ к широкому спектру невероятно быстрых маршрутов сортировки, например:
#define SORT_NAME int64 #define SORT_TYPE int64_t #define SORT_CMP ( x , y ) (( x ) - ( y )) #include "sort.h" / * Теперь у вас есть доступ к int64_quick_sort, int64_tim_sort и т. д., например, * /
int64_quick_sort ( обр. , 128 ); / * Предполагается, что у вас есть int * arr или int arr [128]; * /
Это должно быть как минимум в два раза быстрее, чем стандартная библиотека qsort, поскольку она не использует указатели на функции и имеет множество других вариантов алгоритма сортировки на выбор.
Он находится на C89, поэтому должен работать практически во всех компиляторах C.
Ответы:
qsort()
это функция, которую вы ищете. Вы вызываете его с помощью указателя на ваш массив данных, количества элементов в этом массиве, размера каждого элемента и функции сравнения.Он творит свое волшебство, и ваш массив сортируется на месте. Пример ниже:
источник
return (f > s) - (f < s);
qsort
Функция« Пункт 4 »Если два элемента сравниваются как равные, их порядок в результирующем отсортированном массиве не указан».Стандартная библиотека C / C ++
<stdlib.h>
содержитqsort
функцию.Это не лучшая реализация быстрой сортировки в мире, но она достаточно быстрая и ОЧЕНЬ ЛЕГКАЯ для использования ... формальный синтаксис qsort:
Единственное, что вам нужно реализовать, это функция compare_function, которая принимает два аргумента типа «const void», которые могут быть преобразованы в соответствующую структуру данных, а затем возвращать одно из этих трех значений:
1. Сравнение списка целых чисел :
просто бросить а и Ь в целые числа , если это
x < y
,x-y
имеет отрицательное значение ,x == y
,x-y = 0
,x > y
,x-y
положительныйx-y
ярлык способ сделать это :) обратным ,*x - *y
чтобы*y - *x
при сортировке в уменьшении / обратный порядок2. Сравнение списка строк :
Для сравнения строк вам нужна
strcmp
функция внутри<string.h>
библиотеки.strcmp
по умолчанию вернет -ve, 0, ve соответственно ... для сортировки в обратном порядке, просто измените знак, возвращаемый strcmp3. Сравнение чисел с плавающей запятой :
4. Сравнение записей по ключу :
Иногда вам нужно отсортировать более сложные вещи, например, записи. Вот самый простой способ сделать это с помощью
qsort
библиотеки.источник
int
значения, переданные в компаратор,int *
замаскированы подvoid *
.char *
Таким образом, при сортировке массива значения, переданные в компаратор,char **
замаскированы какvoid *
. Таким образом, правильный код должен быть:int compare_function(const void *a,const void *b) { return (strcmp(*(char **)a, *(char **)b)); }
.if (x > y) return +1; else if (x < y) return -1; else return 0;
, или, если вам нужно простое выражение, тогдаreturn (x > y) - (x < y);
. Это всегда оценивает два сравнения на уровне C, но оптимизатор может этого избежать. Вычитание не работает для значений без знака. Первая версия хорошо работает, когда вы имеете дело с серией сравнений - сначала сравниваете 2 целочисленных члена структуры, и если они равны, то два двойных, затем две строки и т.д. в C, а также в Perl.Конечно:
qsort()
это реализация сортировки (не обязательно быстрой сортировки, как следует из названия).Попробуйте man 3 qsort или прочтите http://linux.die.net/man/3/qsort
источник
qsort
не обязательно реализовывать с помощью Quicksort.Хотя он и не входит в стандартную библиотеку, https://github.com/swenson/sort имеет только два файла заголовков, которые вы можете включить, чтобы получить доступ к широкому спектру невероятно быстрых маршрутов сортировки, например:
Это должно быть как минимум в два раза быстрее, чем стандартная библиотека
qsort
, поскольку она не использует указатели на функции и имеет множество других вариантов алгоритма сортировки на выбор.Он находится на C89, поэтому должен работать практически во всех компиляторах C.
источник
попробуйте
qsort
в stdlib.h.источник
Используйте
qsort()
в<stdlib.h>
.@paxdiablo
qsort()
Функция соответствует ISO / IEC 9899: 1990 (`` ISO C90 '').источник
Есть несколько функций сортировки C, доступных в
stdlib.h
. Вы можете сделатьman 3 qsort
на машине unix, чтобы получить их список, но они включают:источник