目录
1.冒泡排序:
1.1 解释冒泡排序:
1.2冒泡排序的代码表示:
2.qsort排序:
2.1 qsort排序的概念,及对于比冒泡排序所具有的优点。
2.2 qsort排序的代码表示:
冒泡排序可以将排列顺序无规律的数组排列成升序的数组,例如以下面的数组进行举例:
8 7 9 3 4 5 1 6 2
冒泡排序的总体思想就:让两个相邻的元素进行比较,如果不满足所期望的顺序(例如从小到大)则交换两个数的位置。下面将通过对上面所列举的无规律数组通过冒泡排序的方法,将其排列成从小打到的顺序:
1.1先将8 7进行比较,因为8 > 7,所以,两个数字交换位置:
7 8 9 3 4 5 1 6 2
1.2再将 8 9 进行比较,因为 8 < 9,所以不动
1.3再将9 3 进行比较,因为9 > 3,所以9 3 位置互换:
7 8 3 9 4 5 1 6 2
按照这个顺序依次向后排序,当9 和 2完成排序后,数字的排列变为:
7 8 3 4 5 1 6 2 9
此时,数组中中最大的数字,会被排序到最后一位,以上的步骤称之为一趟冒泡排序
再完成了一趟给冒泡排序后,会再对此时数组的第一个数字进行上述步骤,在这趟冒泡排序也完成后,这串数字会变成:
7 3 4 5 1 6 2 8 9
依次重复上述步骤,最后这串数字会变成从小到大的排列顺序:
1 2 3 4 5 6 7 8 9
不难看出,对一个含有n个数字的数字串,整个冒泡排序完成时,所经历的冒泡排序的趟数为:n-1
第i趟冒泡排序中(i>=1 && i <=n-1),进行相邻两个数比较并交换的次数是 n - i -1,例如第一趟冒泡排序,只是拿第一个数和其他的8个数进行比较,第二趟冒泡排序时,因为第一趟冒泡排序已经将最大的数排到最后,所以不需要考虑最后一个数,只需要将此时的第一个数和其余的七个数进行比较,以此类推。
void bubble_sort(int * arr, int sz)
{
int i = 0;
for (i = 0; i < sz-1; i++)
{
int j = 0;
for (j = 0; j < sz - i - 1; j++)
{
if (arr[j] > arr[j + 1])
{
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
}
}
int main()
{
int arr[9] = { 8,7,9,3,4,5,1,6,2 };
int sz = 0;
sz = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr, sz);
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
结果如下:
虽然冒泡排序可以将无规律的数字串排成有序数字串,但是冒泡排序只可以对Int类型的数字进行拍排序,对于字符,字符串,结构体等无法进行。为了解决上述问题,下面将引入qsort排序
1.qsort排序是快速排序
2qsort适合任意类型数据的排序
qsort函数一共有四个参数,分别是:
用代码表示,则格式为:
void qosrt(void* base,
size_t num,
size_t size,
int(*compare)(const void*, const void*));
其中,base表示需要被排序的数组的地址
size_t num表示被排序数组的元素个数
size_t size表示被排序数组的单个元素的大小
最后的一长串表示一个函数指针, 并且这个函数指针需要自己去构建。
依然是用冒泡排序中不规律别的数组举例子:
8 7 9 3 4 5 1 6 2
首先确认qosrt函数的四个参数:
qsort(arr, sz, sizeof(arr[0]), compare_int);
在前面的文章中多次提到,数组名= 数组首元素地址,所以,第一个参数可以用arr来提供需要被排序的数组地址
第二个参数,用sz来提供被排序数组中的元素个数,其中sz:
int sz = sizeof(arr) / sizeof(arr[0]);
第三个参数是被排序数组的单个元素的大小,可以用sizeof(arr[0])来表示。
第四个参数就是需要后面自己来写的比较函数。比较函数如下:
int compare_int(const void* p1, const void* p2)
{
return(*(int*)p1 - *(int*)p2);
}
这里需要注意的是,前面提到过,qsort可以对任意类型的数据进行排序,所以,qsort函数对于参数的类型的选择,使用void*进行表示,void*可以匹配任意类型的数据,但是,因为void*可以匹配任意类型的数据,所以在前面提到的不同类型指针的特殊性质,即指针和整数的加减以及指针的访问权限在void*指针上均不满足。所以,在书写比较函数的代码时,需要进一步将void*类型的数据,强制转换成被排序的数组的数据类型,例如,上面对int型的数据进行排序,则在书写比较函数时,需要将void*转为int*类型。
至于上述代码中的返回值,则是qsort函数自身所规定,即:
当元素p1 > p2时,返回值 >0
当元素p1 < p2时,返回值 < 0
当元素p1 = p2时,返回值 = 0
所以,整体的代码是:
(注:qsort排序默认是升序,如果想实现降序,只需将返回值的p1 p2位置颠倒即可)
int compare_int(const void* p1, const void* p2)
{
return(*(int*)p1 - *(int*)p2);
}
void print(int* arr, int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
}
void test1()
{
int arr[9] = { 8,7,9,3,4,5,1,6,2 };
int sz = sizeof(arr) / sizeof(arr[0]);
qsort(arr, sz, sizeof(arr[0]), compare_int);
print(arr, sz);
}
int main()
{
test1();
return 0;
}
打印结果为:
这篇文章只是介绍了qsort在进行整型数据排序时的情况,对其他的数据类型并没有提及,且只是对qsort排序及函数进行了简单的应用解释,对qsort函数如何实现及原理并没有说明,这些内容将在下一篇文章中进行说明。