目录
一、冒泡排序
冒泡排序作为最简单的排序之一,核心思想是两两比较,这里以升序为例:
首先给一个数组:{9,8,7,6,5,4,3,2,1,0}
第一轮比较:
两两比较,9>8,交换:{8,9,7,6,5,4,3,2,1,0}
9>7,交换:{8,7,9,6,5,4,3,2,1,0}
9>6,交换:{8,7,6,9,5,4,3,2,1,0}
……
9>0,交换:{8,7,6,5,4,3,2,1,0,9}
第二轮比较:
两两比较,8>7,交换:{7,8,6,5,4,3,2,1,0,9}
8>6,交换:{7,6,8,5,4,3,2,1,0,9}
8>5,交换:{7,6,5,8,4,3,2,1,0,9}
……
8<9,不交换:{7,6,5,4,3,2,1,0,8,9}
第三轮比较:……
最后实现数组升序排列:{0,1,2,3,4,5,6,7,8,9}。
从上面推导过程可以看出,后一位比前一位小就要交换,以此循环,有两层循环,且里层循环过一轮就少一次,用代码这样实现
void BubbleSort(int* arr, int n)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n - 1 - i; j++)
{
if (arr[j] > arr[j + 1])
{
Swap(&arr[j], &arr[j - 1]);
}
}
}
}
其中Swap的实现:
void Swap(int* x, int* y)
{
int tmp = *x;
*x = *y;
*y = tmp;
}
二、使用qsort
1).定义与使用
2).整数排序
3).结构体排序
结构体定义:
struct Stu
{
char name[20]; //学⽣
int age; //年龄
};
1.按年龄
//按照年龄来⽐较
int cmp_stu_by_age(const void* e1, const void* e2)
{
return ((struct Stu*)e1)->age - ((struct Stu*)e2)->age;
}
//按照年龄来排序
void test3()
{
struct Stu s[] = { {"zhangsan", 20}, {"lisi", 30}, {"wangwu", 15} };
int sz = sizeof(s) / sizeof(s[0]);
qsort(s, sz, sizeof(s[0]), cmp_stu_by_age);
}
2.按名字
//按照名字来⽐较
int cmp_stu_by_name(const void* e1, const void* e2)
{
return strcmp(((struct Stu*)e1)->name, ((struct Stu*)e2)->name);
}
//按照名字来排序
void test2()
{
struct Stu s[] = { {"zhangsan", 20}, {"lisi", 30}, {"wangwu", 15} };
int sz = sizeof(s) / sizeof(s[0]);
qsort(s, sz, sizeof(s[0]), cmp_stu_by_name);
}
其中strcmp是字符串比较函数
三、模拟实现qsort
使用回调函数,采用冒泡排序的方式
qsort的接收参数:
这是冒泡排序的基本结构:
首先我们不知道需要排序的是整型,浮点型还是字符串,所以要修改让其可以接收各种类型,(一切为了随机):
然后,由于我们不知道元素类型,因此在比较前后元素时,我们无法确定将其转换成何种类型来比较,但由于元素大小size已知,且单位是字节,这样我们可以一个字节一个字节进行比较,即全部强制类型转化为char*。
接下来是Swap函数,由于是一个一个字节比较,同理,交换时也是一个一个字节交换:
注意:在使用qsort时需要我们自己写出比较方式。
测试:
此时,我们就实现了冒泡排序模拟实现qsort。
代码:
void Swap(char* x, char* y, size_t size)
{
for (size_t i = 0; i < size; i++)
{
char tmp = *(x + i);
*(x + i) = *(y + i);
*(y + i) = tmp;
}
}
void BubbleSort(void* base, size_t num, size_t size, int(*cmp)(const void* e1, const void* e2))
{
for (size_t i = 0; i < num; i++)
{
for (size_t j = 0; j < num - 1 - i; j++)
{
if (cmp((char*)base + j * size, (char*)base + (j + 1) * size) > 0)
{
Swap((char*)base + j * size, (char*)base + (j + 1) * size, size);
}
}
}
}
完,感谢阅读。