1. 冒泡排序的思想
冒泡排序的思想:两两相邻的元素比较,不满足顺序就交换,满足顺序就找下一对。
举例:
如图所示,有这样一个完全倒序的数组,从第一对开始比较,不满足顺序则交换,交换之后满足顺序了,则判断下一对是否满足顺序,若不满足则继续交换,以此类推,可见,经过若干次交换之后,第一个元素 9 排到了最终的位置,那么我们说这就是完成了 一趟 排序。
2. 确定趟数
那么我们一共需要进行多少趟排序呢?
由上述示例,一趟排序确定了 1 个元素的位置,那么 10 个元素则一共需要 9 趟排序,因此 sz 个元素一共需要 sz-1 趟排序
3. 确定每一趟中的交换次数
如图所示,第一趟确定了 1 个数的最终位置,则10个元素进行了9次交换,第二趟排序确定了 2 个数的最终位置,则剩余 9 个元素进行了 8 次交换,若用 for
循环来进行每趟的内部排序,则第 i 趟排序需要进行 sz-1-i
次交换,其中 i 为交换的趟数,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;
}
}
4. 代码实现
//冒泡排序
void Print_arr(int* arr,int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", *(arr + i));
}
}
void bubble_sort(int* arr, int sz)
{
//确定趟数
int i = 0;
for (i = 0; i < sz - 1; i++)
{
int flag = 1;//假设已经有序
//每一趟内部交换
int j = 0;
for (j = 0; j < sz - 1 - i; j++)
{
if (arr[j] > arr[j + 1])
{
flag = 0;//不是有序
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
if (flag == 1)//判断已经有序
{
break;
}
}
}
void input(int* arr,int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
scanf("%d", arr + i);
}
}
int main()
{
int arr[10] = { 0};
int sz = sizeof(arr) / sizeof(arr[0]);
//输入一些值
input(arr, sz);
//进行冒泡排序
bubble_sort(arr, sz);
//在屏幕上打印
Print_arr(arr,sz);
return 0;
}
flag 的含义:若数组内的数已经有序,例如:0 1 2 3 4 5 6 7 8 9,若对这个数组进行逐趟排序,数组不会有任何的变化,且会浪费很多时间,因此设立 flag ,进行一趟判断,若第一趟中没有元素发生交换,则 flag 不会发生变化,也就意味着该数组中的元素已经有序,不需要再进行后续的判断了,大大节约了时间成本。