比较相邻的元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
针对所有的元素重复以上的步骤,除了最后一次。
持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。
图像展示
规律:十个数的冒泡:
第一趟
10 9 8 7 6 5 4 3 2 1 |
9 10 8 7 6 5 4 3 2 1 |
9 8 10 7 6 5 4 3 2 1 |
9 8 7 10 6 5 4 3 2 1 |
...... |
9 8 7 6 5 4 3 2 1 10 |
比较了九次
第二趟(此次不用管10。仅对前九个数进行比较)
9 8 7 6 5 4 3 2 1 10 |
8 9 7 6 5 4 3 2 1 10 |
8 7 9 6 5 4 3 2 1 10 |
8 7 6 9 5 4 3 2 1 10 |
...... |
8 7 6 5 4 3 2 1 9 10 |
比较了八次(不考虑10)
第三趟(此次不用管9和10。仅对前八个数进行比较)
8 7 6 5 4 3 2 1 9 10 |
7 8 6 5 4 3 2 1 9 10 |
7 6 8 5 4 3 2 1 9 10 |
7 6 5 8 4 3 2 1 9 10 |
...... |
7 6 5 4 3 2 1 8 9 10 |
比较了七次(不考虑9 10)
...
...
完成十个数的排序:总的循环需要进行九趟;每趟的比较对数sz-1-i
总结:完成n个数的排序,总趟数为n-1,每趟进行的比较对数为sz-1-i
主函数框架
int main()
{
int arr[]={10,9,8,7,6,5,4,3,2,1};
int i=0;//下标
int sz=sizeof(arr)/sizeof(arr[0]);
//对arr进行排序 排成升序
bubble_sort(arr,sz);
///arr是数组 数组传参传的是第一个元素的地址
for(i=0;i<sz;i++)
{
printf("%d ",arr[i]);
}
return 0;
}
注:arr是数组 数组传参传的是第一个元素的地址
例外:
1.sizeof(数组名),计算整个数组的大小,sizeof内部单独放一个数组名,数组名表示整个数组,单位是字节
2.&数组名,取出的是数组的地址 。&数组名,数组名表示整个数组
定义函数框架
确定冒泡排序的趟数
void bubble_sort(int arr[],int sz)
{
int i=0;
for(i=0;i<sz-1;i++);
{
//这里为趟数所需要进行的比较次数做预留空间
}
}
趟数所需要进行的比较次数
for(i=0;i<sz-1;i++)
{
int j;//比较的对数
for(j=0;j<sz-1-i;j++)
{
//为开始比较做准备
}
注:j<sz-1-i(可以看成是每次都保持在总趟数的基础上对其进行了减i)(或者说随着总趟数的减少,比较的次数总是在该趟数的基础上少一次,而该趟数需要被我们转换成在总趟数的基础上方便找到规律)
因为每次随着趟数的增加,其中数字的比较总是依次在总数的基础上减一后继续减一,
由于i从0开始计算,而后一次的减一又恰好能对应上i每次的加一,
所以是j<sz-1-i(也就是9-0;9-1;9-2......)
开始比较的过程
也就是交换位置的过程
if(arr[j]>arr[j+1])
{
int tmp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=tmp;
}
优化
因为存在如果有趟数在要排序的时候已经有序了的情况
此时我们就不用对这趟数进行比较 这样能节约运行的速度和空间
在趟数循环里加入
且比较完成后令
即
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;
flag=0;
}
}
并且对比较的数进行比较后 如果发现已经有序了 此时的flag又对于1 则直接退出最外层循环
注:break只能用于循环语句和开关语句 在if中使用时 外层必须有循环才能使用 否则不能使用
void bubble_sort(int arr[],int sz)//排完序就可以了 所以不需要返回值
{
int i=0;
for(i=0;i<sz-1;i++)
{
int flag=1;
int j;
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;
flag=0;
}
}
if(flag==1)
{
break;
}
}
}
最终代码
#include<stdio.h>
void bubble_sort(int arr[],int sz)//排完序就可以了 所以不需要返回值
{
//确定冒泡排序的趟数
//确定多少个元素(n个元素需要n-1趟)
int i=0;
for(i=0;i<sz-1;i++)
{
//每一趟冒泡排序
int flag=1;
//假设这趟要排序的数组已经有序了
int j;
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;
flag=0;//本趟排序的数据其实是不完全排序
}
}
if(flag==1)
{
break;
}
}
}
int main()
{
int arr[]={10,9,8,7,6,5,4,3,2,1};
int i=0;
int sz=sizeof(arr)/sizeof(arr[0]);
//对arr进行排序 排成升序
bubble_sort(arr,sz);
///arr是数组 数组传参传的是第一个元素的地址
for(i=0;i<sz;i++)
{
printf("%d ",arr[i]);
}
return 0;
}