排序
本章描述了直接和间接(使用索引)排序数据的函数。所有函数都使用堆排序算法。堆排序是一种O(N logN)算法,在执行时不需要任何额外的存储空间。它还提供了一致的性能,其最差情况(有序数据)的运行时间并不比平均情况和最佳情况长多少。请注意,堆排序算法并不保留相等元素的相对顺序—它是一种不稳定的排序。但是,在使用这些函数时,相同元素的结果顺序在不同平台上是一致的。
12.1 排序对象
下面的函数提供了标准库函数qsort()的简单替代。它用于缺少qsort()的系统,而不是作为它的替代。只要可能,就应该使用函数qsort(),因为它更快,并且可以提供相等元素的稳定排序。qsort()的文档可以在GNU C库参考手册中找到。
本节中描述的函数定义在头文件gsl_heapsort.h中。
void gsl_heapsort(void * array, size_t count, size_t size,
gsl_comparison_fn_t compare)
本函数使用比较函数compare将数组中每个size大小的count元素按升序排序。比较函数的类型定义为:
gsl_comparison_fn_t
int (*gsl_comparison_fn_t) (const void *a, const void * b) |
如果第一个参数小于第二个参数,比较函数应该返回一个负整数;如果两个参数相等,则返回0;如果第一个参数大于第二个参数,则返回一个正整数。
例如,可以使用下面的函数将双精度数排序为升序数字。
int compare_double (const double * a, const double * b) { if (*a > *b) return 1; else if (*a < *b) return -1; else return 0; } |
执行排序的适当函数调用是:
gsl_heapsort (array, count, sizeof(double), compare_doubles); |
注意,与qsort()不同,堆排序算法不能通过指针算法变成稳定的排序。比较函数中相等元素的指针的技巧对堆排序算法不起作用。堆排序算法执行数据的内部重排,从而破坏其初始排序。
int gsl_heapsort_index(size_t * p, const void * array, size_t count, size_t size,
gsl_comparison_fn_t compare)
本函数使用比较函数compare将数组中每个size大小的count元素按升序间接排序。得到的排列结果存储在长度为n的数组p中。p的元素给出了数组元素的索引,如果数组在适当的位置进行了排序,那么数组元素将存储在该位置。p的第一个元素给出array中最小元素的索引,p的最后一个元素给出array中最大元素的索引。数组本身没有改变。
12.2 排序向量
下面的函数将直接或间接地对数组或向量的元素排序。它们是使用普通后缀规则为所有实数和整数类型定义的。例如,数组函数的浮点数版本是gsl_sort_float()和gsl_sort_float_index()。对应的向量函数是gsl_sort_vector_float()和gsl_sort_vector_float_index()。这些原型可以在头文件gsl_sort_float.h中找到。可以使用头文件gsl_sort.h和gsl_sort_vector.h包含完整的原型集。
没有用于对复杂数组或向量排序的函数,因为复数的排序不是唯一定义的。通过计算包含复杂元素大小的实向量来对复杂向量排序,并间接地对这个向量排序。结果索引给出了原始复向量的适当顺序。
void gsl_sort(double * data, const size_t stride, size_t n)
本函数将具有步长stride的数组data的n个元素按升序进行排序。
void gsl_sort2(double * data1, const size_t stride1, double * data2,
const size_t stride2, size_t n)
本函数将包含步长stride1的数组data1的n个元素按升序排序,同时将包含步长stride2的数组data2的n个元素按升序排序。
void gsl_sort_vector(gsl_vector * v)
本函数将向量v的元素按照数值升序进行排序。
void gsl_sort_vector2(gsl_vector *vl, gsl_vector * v2)
本函数将向量v1的元素按照数值升序进行排序,同时对向量v2进行相同的排序。
void gsl_sort_index(size_t * p, const double * data, size_t stride, size_t n)
本函数以步长为stride的方式对数组data的n个元素按升序间接排序,将排列结果存储在p中。数组p必须预先分配足够的长度以存储n个元素的排列。p的元素给出数组元素存储位置的索引,如果数组在适当的位置进行了排序,那么它将被存储在那个位置。数组data不会改变。
int gsl_sort_vector_index(gsl_permutation * p, const gsl_vector * v)
本函数以间接的方式对向量的元素进行升序排序,存储排列结果在p中。如果向量在适当的位置进行了排序,p的元素给出向量元素存储位置的索引。p的第一个元素给出v的最小元素的索引,p的最后一个元素给出v的最大元素的索引。向量v不会改变。