一、冒泡排序
思想——两两相邻元素进行比较
例如:利用冒泡排序实现对数组9 8 7 6 5 4 3 2 1 0 进行升序排列
![](https://i-blog.csdnimg.cn/blog_migrate/65051262378c08dbe45034e1b43299ae.png)
一趟冒泡排序使一个数字到达最终位置,所以10个元素进行9趟冒泡排序。
代码实现:
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-1-i; 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,6,5,4,3,2,1,0 };
int 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;
}
注:冒泡排序只能对整数进行排序,功能有限。
二、库函数中有一个排序函数——qsort函数
qsort函数底层是快速排序,与冒泡排序方式方法不同。
头文件:#include<stdlib.h>
![](https://i-blog.csdnimg.cn/blog_migrate/559d340b13c8e5d59a88c404b37bd3f7.png)
void *base——目标数组起始地址
size_t num——数组元素个数
size_t width——一个元素所占字节大小
const void *elem1——第一个元素地址
const void *elem2——第二个元素地址
void*指针:
任意类型的地址都可以赋给void*指针
void*指针不可以解引用
void*指针不可进行++或--操作
(一)使用qsort排序整型
//实现一个比较整型的函数
int cmp_int(const void* e1, const void* e2)
{
return *(int*)e1 - *(int*)e2;
}
int main()
{
int arr[] = { 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);
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
(二)使用qsort排序结构体
struct Stu
{
char name[20];
int age;
};
//按照学生的年龄排序
int cmp_stu_by_age(const void* e1, const void* e2)
{
return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
int main()
{
struct Stu s[3] = { {"zhangsan",20}, {"lisi", 50}, {"wangwu", 33} };
int sz = sizeof(s) / sizeof(s[0]);
qsort(s, sz, sizeof(s[0]), cmp_stu_by_age);
}
struct Stu
{
char name[20];
int age;
};
//按照学生姓名排序
int cmp_stu_by_name(const void* e1, const void* e2)
{
return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
}
int main()
{
struct Stu s[3] = { {"zhangsan",20}, {"lisi", 50}, {"wangwu", 33} };
int sz = sizeof(s) / sizeof(s[0]);
qsort(s, sz, sizeof(s[0]), cmp_stu_by_name);
}
改造冒泡排序,使得这个函数可以排序任意指定的数组
使用bubble_sort函数排序整型数组
int cmp_int(const void* e1, const void* e2)
{
return *(int*)e1 - *(int*)e2;
}
void Swap(char* buf1, char* buf2, int width)
{
int i = 0;
for (i = 0; i < width; i++)
{
char tmp = *buf1;
*buf1 = *buf2;
*buf2 = tmp;
buf1++;
buf2++;
}
}
void bubble_sort(void* base, size_t sz, size_t width, int (*cmp)(const void* e1, const void* e2))
{
//趟数
size_t i = 0;
for (i = 0; i < sz - 1; i++)
{
//一趟冒泡排序的过程
size_t j = 0;
for (j = 0; j < sz - 1 - i; j++)
{
if (cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0)
{
//交换
Swap((char*)base + j * width, (char*)base + (j + 1) * width, width);
}
}
}
}
//使用我们自己写的bubble_sort函数排序整型数组
int main()
{
int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
int sz = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr, sz, sizeof(arr[0]), cmp_int);
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
}