Có bất kỳ chức năng thư viện nào có sẵn trong thư viện chuẩn C để thực hiện sắp xếp không?
Có bất kỳ chức năng thư viện nào có sẵn trong thư viện chuẩn C để thực hiện sắp xếp không?
Câu trả lời:
qsort()
là chức năng bạn đang tìm kiếm. Bạn gọi nó bằng một con trỏ đến mảng dữ liệu của bạn, số phần tử trong mảng đó, kích thước của mỗi phần tử và một hàm so sánh.
Nó thực hiện điều kỳ diệu và mảng của bạn được sắp xếp đúng vị trí. Một ví dụ sau:
#include <stdio.h>
#include <stdlib.h>
int comp (const void * elem1, const void * elem2)
{
int f = *((int*)elem1);
int s = *((int*)elem2);
if (f > s) return 1;
if (f < s) return -1;
return 0;
}
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]);
return 0;
}
return (f > s) - (f < s);
qsort
Hàm" Điểm 4 "Nếu hai phần tử so sánh bằng nhau, thứ tự của chúng trong mảng đã sắp xếp kết quả là không xác định."
Thư viện chuẩn C / C ++ <stdlib.h>
chứa qsort
hàm.
Đây không phải là cách triển khai sắp xếp nhanh nhất trên thế giới nhưng nó đủ nhanh và RẤT DỄ DÀNG được sử dụng ... cú pháp chính thức của qsort là:
qsort(<arrayname>,<size>,sizeof(<elementsize>),compare_function);
Điều duy nhất bạn cần triển khai là hàm so sánh, có hai đối số kiểu "const void", có thể được ép kiểu đến cấu trúc dữ liệu thích hợp, rồi trả về một trong ba giá trị sau:
1. So sánh danh sách các số nguyên :
chỉ đơn giản là cast a và b để số nguyên nếu x < y
, x-y
là tiêu cực, x == y
, x-y = 0
, x > y
, x-y
là tích cực
x-y
là một cách phím tắt để làm điều đó :) đảo ngược *x - *y
để *y - *x
để phân loại trong việc giảm / thứ tự ngược lại
int compare_function(const void *a,const void *b) {
int *x = (int *) a;
int *y = (int *) b;
return *x - *y;
}
2. So sánh danh sách các chuỗi :
Để so sánh chuỗi, bạn cần strcmp
hàm bên trong <string.h>
lib.
strcmp
mặc định sẽ trả về -ve, 0, ve thích hợp ... để sắp xếp theo thứ tự ngược lại, chỉ cần đảo ngược dấu hiệu được trả về bởi strcmp
#include <string.h>
int compare_function(const void *a,const void *b) {
return (strcmp((char *)a,(char *)b));
}
3. So sánh số dấu phẩy động :
int compare_function(const void *a,const void *b) {
double *x = (double *) a;
double *y = (double *) b;
// return *x - *y; // this is WRONG...
if (*x < *y) return -1;
else if (*x > *y) return 1; return 0;
}
4. So sánh các bản ghi dựa trên một khóa :
Đôi khi bạn cần sắp xếp những thứ phức tạp hơn, chẳng hạn như bản ghi. Đây là cách đơn giản nhất để làm điều đó bằng cách sử dụng qsort
thư viện.
typedef struct {
int key;
double value;
} the_record;
int compare_function(const void *a,const void *b) {
the_record *x = (the_record *) a;
the_record *y = (the_record *) b;
return x->key - y->key;
}
int
, các giá trị được chuyển đến bộ so sánh đều được int *
ngụy trang dưới dạng void *
. char *
Do đó, khi sắp xếp một mảng , các giá trị được chuyển đến bộ so sánh đều được char **
ngụy trang dưới dạng void *
. Do đó, mã chính xác cần phải được: 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;
hoặc nếu bạn muốn một biểu thức đơn giản return (x > y) - (x < y);
. Điều này luôn đánh giá hai so sánh ở cấp độ C, nhưng trình tối ưu hóa có thể tránh được điều đó. Phép trừ không hoạt động trên các giá trị không dấu. Phiên bản đầu tiên hoạt động tốt khi bạn xử lý một loạt phép so sánh - trước tiên so sánh 2 phần tử nguyên của một cấu trúc và nếu chúng bằng nhau, thì hai phần nhân đôi, sau đó là hai chuỗi, v.v. Có nhiều cách để làm điều đó, trong C cũng như Perl.
Chắc chắn: qsort()
là một triển khai của một loại (không nhất thiết phải nhanh như tên của nó có thể gợi ý).
Hãy thử man 3 qsort hoặc đọc tại http://linux.die.net/man/3/qsort
qsort
không cần phải thực hiện bằng Quicksort.
Mặc dù không nằm trong thư viện chuẩn chính xác, https://github.com/swenson/sort chỉ có hai tệp tiêu đề mà bạn có thể đưa vào để có quyền truy cập vào một loạt các quy trình sắp xếp cực kỳ nhanh chóng, như vậy:
#define SORT_NAME Int64 #define SORT_TYPE int64_t #define SORT_CMP ( x , y ) (( x ) - ( y )) #include "sort.h" / * Bây giờ bạn có thể truy cập int64_quick_sort, int64_tim_sort vv, ví dụ * / int64_quick_sort ( arr , 128 ); / * Giả sử bạn có một số int * arr hoặc int arr [128]; * /
Điều này phải nhanh hơn ít nhất hai lần so với thư viện tiêu chuẩn qsort
, vì nó không sử dụng con trỏ hàm và có nhiều tùy chọn thuật toán sắp xếp khác để lựa chọn.
Nó nằm trong C89, vì vậy về cơ bản sẽ hoạt động trong mọi trình biên dịch C.
thử qsort
trong stdlib.h.
Sử dụng qsort()
trong <stdlib.h>
.
@paxdiablo qsort()
Chức năng này tuân theo ISO / IEC 9899: 1990 (`` ISO C90 '').
Có một số chức năng sắp xếp C có sẵn trong stdlib.h
. Bạn có thể thực hiện man 3 qsort
trên máy unix để lấy danh sách nhưng chúng bao gồm: