什么是冒泡排序法
冒泡排序(Bubble Sort),是一种计算机科学领域的较简单的排序算法。它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从Z到A)错误就把他们交换过来。走访元素的工作是重复地进行直到没有相邻元素需要交换,也就是说该元素列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名"冒泡排序"。
方法一:
#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable:6031)
#include <stdio.h>
void bubble_sort(int arr[],int sz)
{
for (int i = 0; i < sz - 1; i++)
{
int flag = 1;//判断排序是否完成的标志位
for (int j = 0; j < sz-i-1; j++)
{
//交换
if (arr[j]>arr[j+1])
{
//通过创建中间变量temp来交换两个数组中的数据
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
flag = 0;
}
}
if (flag == 1)
{
break;
}
}
}
int main()
{
int arr[10] = { 0 };
printf("请输入要进行冒泡排序的10个数字:\r\n");
for (int i = 0; i < 10; i++)
{
scanf("%d", &arr[i]);
}
printf("输入的数字是:");
for (int i = 0; i < 10; i++)
{
printf("%d ", arr[i]);
}
printf("\r\n");
bubble_sort(arr,sizeof(arr)/sizeof(arr[0]));
printf("冒泡法排序后的结果为:");
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
{
printf("%d ", arr[i]);
}
return 0;
}
程序运行结果:
方法一较为直观,也是现在网上流行最多的写法,但是我在这里多加了一个变量flag,若这次排序没有交换,则判断排序完成,可以通过break提前结束冒泡排序,让时间复杂度下降了,达到加快程度运行的目的。
方法二(使用回调函数,模拟实现qsort(采用冒泡的方式)):
#define _CRT_SECURE_NO_WARNINGS 1
#pragma warning(disable:6031)
#include <stdio.h>
#include <string.h>
struct MyStruct
{
char name[20];
int age;
};
void Swap(char* buf1, char* buf2,int width)
{
for (int i = 0; i < width; i++)
{
char temp = *buf1;
*buf1 = *buf2;
*buf2 = temp;
buf1++;
buf2++;
}
}
void bubble_sore(void* base, int sz, int width, int (*cmp)(void* e1, void* e2))
{
//趟数
for (int i = 0; i < sz - 1; i++)
{
//每一趟的比较次数
for (int 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);
}
}
}
}
int cmp_int(const void* e1, const void* e2)
{
//比较两个整形值
return *(int*)e1 - *(int*)e2;
}
void test01()
{
int arr[10] = { 9,8,7,6,5,4,3,2,1,0 };
int sz = sizeof(arr) / sizeof(arr[0]);
bubble_sore(arr, sz, sizeof(arr[0]), cmp_int);
for (int i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
int cmp_stu_by_age(const void* e1, const void* e2)
{
return ((struct MyStruct*)e1)->age - ((struct MyStruct*)e2)->age;
}
int cmp_stu_by_name(const void* e1, const void* e2)
{
//比较名字就是比较字符串
//字符串比较不能直接用<>=来比较,应该用strcmp函数来比较
return strcmp(((struct MyStruct*)e1)->name, ((struct MyStruct*)e2)->name);
}
void test02()
{
struct MyStruct mystruct[3] = {{"zhangsan",10},{"lisi",20},{"wangwu",30}};
int sz = sizeof(mystruct) / sizeof(mystruct[0]);
bubble_sore(mystruct, sz, sizeof(mystruct[0]), cmp_stu_by_age);
for (int i = 0; i < sz; i++)
{
printf("%d \n", mystruct[i].age);
}
bubble_sore(mystruct, sz, sizeof(mystruct[0]), cmp_stu_by_name);
for (int i = 0; i < sz; i++)
{
printf("%s \n", mystruct[i].name);
}
}
int main()
{
test01();
test02();
return 0;
}
程序运行结果
我们在初级使用的时候我们只需要会第一种就行了,如果想要学会第二种需要大量和指针相关的知识,如果感兴趣的话欢迎移步我的另一篇博客,了解一些与指针相关的知识
链接: 【C语言】指针详解