qsort()函数是C语言库函数中的一种排序算法,其用到的排序思想是快速排序(quicksort)。它的独特之处在于可以排序任意类型的数组元素(整形、浮点型、字符串和结构体类型)。
1.函数原型void qsort ( void * base, size_t num, size_t size, int ( * comparator ) ( const void *, const void * ) );
2.参数含义①void * base
:待排序数组的首地址。
②size_t num
:数组元素的个数。
③size_t size
:一个数组元素的大小(所占字节数)。
④int ( * comparator ) ( const void *, const void * ):
首先它是一个函数指针,指向的函数是排序函数;其此所包含的两个参数为所比较元素的地址;最后是参数类型为void*的原因是它的独特之处,可以接收任意类型的参数。
以整形排序为例:
int cmp_int( const void * elem1, const void * elem2 )
{return *(int*)elem1-*(int*)elem2;
}
此函数为自定义函数(比较函数),函数的返回值类型为 int 类型,总共有三种情况:< 0:elem1小于elem2;0:elem1等于elem2;>0:elem1大于elem2。
(const void * elem1, const void * elem2)
两个参数表示所要比较元素的地址,之所以参数的接收类型为 void* 是因为比较元素的类型是不清楚的,只能以 void* 这个万能桶进行接收;const表示指针所指向元素的值无法更改。`
return *(int*)elem1-*(int*)elem2;
对两个元素指针进行强制类型转化为整型指针,再进行解引用获取比较元素的值,最后将两个元素的差值返回。当然也可以根据比较元素的类型将其强制类型转化。
二、比较函数使用案例 1.整型数组int cmp_int(const void* elem1, const void* elem2)
{return *(int*)elem1 - *(int*)elem2;
}
2.字符数组int cmp_char(const void* elem1, const void* elem2)
{return *(char*)elem1 - *(char*)elem2;
}
3.double型数组int cmp_double(const void* elem1, const void* elem2)
{return *(double*)elem1 >*(double*)elem2 ? 1 : -1;
}
注:此函数返回类型为 int 型,浮点型相减的数字会丢失小数点后的数字从而造成误差。若差值为大于零且小于一,则返回值会被设置为零。
4.字符串 1.按字符串首字母进行排序int cmp_string(const void* elem1, const void* elem2)
{return *(char*)elem1 - *(char*)elem2;
}
2.按字符串长度进行排序int cmp_string(const void* elem1, const void* elem2)
{return strlen((char * )elem1) >strlen((char * )elem2) ? 1 : -1;
}
3.按字典进行排序int cmp_string(const void* elem1, const void* elem2)
{return strcmp((char*)elem1,(char*)elem2);
}
5.结构体struct Stu
{char name[10];
int grade;
} s;
1.一级排序:对所有学生进行名字排序。
int cmp_name(const void* elem1, const void* elem2)
{return strcmp(((Stu*)elem1)->name, ((Stu*)elem2)->name);
}
2.二级排序:若名字相同则按照成绩再进行排序,若有三级排序,以此类推。
int cmp_s(const void* elem1, const void* elem2)
{if ((strcmp(((Stu*)elem1)->name, ((Stu*)elem2)->name))!=0)
return strcmp(((Stu*)elem1)->name, ((Stu*)elem2)->name);
else
return ((Stu*)elem1)->grade - ((Stu*)elem2)->grade;
}
三、qsort函数完整使用案例
1.整型数组int cmp_int(const void* elem1, const void* elem2)
{return *(int*)elem1 - *(int*)elem2;
}
int main()
{int arr[10] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(arr[0]), cmp_int);
for (int i = 0; i< sz; i++)
{printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
2.字符数组int cmp_char(const void* elem1, const void* elem2)
{return *(char*)elem1 - *(char*)elem2;
}
int main()
{char arr[] = {'g', 'f', 'e', 'd', 'c', 'b', 'a' };
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(arr[0]), cmp_char);
for (int i = 0; i< sz; i++)
{printf("%c ", arr[i]);
}
printf("\n");
return 0;
}
3.double型数组int cmp_double(const void* elem1, const void* elem2)
{return *(double*)elem1 >*(double*)elem2 ? 1 : -1;
}
int main()
{double arr[10] = {5.32, 9.34, 1.27, 0.28, 0.98, 8.98, 5.69, 4.33, 7.01, 9.90 };
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(arr[0]), cmp_double);
for (int i = 0; i< sz; i++)
{printf("%f ", arr[i]);
}
printf("\n");
return 0;
}
4.字符串
1.按字符串首字母进行排序int cmp_string(const void* elem1, const void* elem2)
{return *(char*)elem1 - *(char*)elem2;
}
int main()
{char arr[6][10] = {"grape", "face", "dog", "cat", "black", "apple" };
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(arr[0]), cmp_string);
for (int i = 0; i< sz; i++)
{printf("%s ", arr[i]);
}
printf("\n");
return 0;
}
2.按字符串长度进行排序int cmp_string(const void* elem1, const void* elem2)
{return strlen((char * )elem1) >strlen((char * )elem2) ? 1 : -1;
}
int main()
{char arr[6][10] = {"aaa", "aaaaa", "aaaaaaa", "aaaaaa", "aa", "aaaa" };
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(arr[0]), cmp_string);
for (int i = 0; i< sz; i++)
{printf("%s ", arr[i]);
}
printf("\n");
return 0;
}
3.按字典进行排序int cmp_string(const void* elem1, const void* elem2)
{return strcmp((char*)elem1,(char*)elem2);
}
int main()
{char arr[6][10] = {"grrfdg","adew","gderfe","abrfggfe","lerf","lmnp" };
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(arr[0]), cmp_string);
for (int i = 0; i< sz; i++)
{printf("%s ", arr[i]);
}
printf("\n");
return 0;
}
5.结构体一级排序与字符串的比较类似,直接看二级排序。
typedef struct Stu
{char name[10];
int grade;
}Stu;
int cmp_s(const void* elem1, const void* elem2)
{if ((strcmp(((Stu*)elem1)->name, ((Stu*)elem2)->name))!=0)
return strcmp(((Stu*)elem1)->name, ((Stu*)elem2)->name);
else
return ((Stu*)elem1)->grade - ((Stu*)elem2)->grade;
}
int main()
{Stu s[] = {{"zhaoda", 89 }, {"qianer", 100 }, {"sunsan", 101 }, {"lisi", 121 }, {"sunsan", 95 }, {"zhaoda",78} };
int sz = sizeof(s) / sizeof(s[0]);
qsort(s, sz, sizeof(s[0]), cmp_s);
for (int i = 0; i< sz; i++)
{printf("%s %d\n", s[i].name,s[i].grade);
}
return 0;
}
你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧