1·什么是冒泡排序?
冒泡排序是一种简单的排序算法,它重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序错误就把他们交换过来。走访元素的工作是重复地进行,直到没有相邻元素需要交换,也就是说该元素列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端,就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”
冒泡排序核心思想:两两相邻元素进行比较,如果不满足条件就交换
2·下面我们用C语言用冒泡排序实现对数组元素进行从小到大的排序:
对于一个数组
int a[10]={5,4,62,7,2,7,8,9,6,35};
我们希望他输出为:
2 4 5 6 7 7 8 9 35 62 (升序)
冒泡排序如何进行排序?
对于数组int a[10]={5,4,62,7,2,7,8,9,6,35}; 首先会以第一个元素5与第二个元素4进行比较
由于5>4,因此将5与4换位 此时变为4,5,62,7,2,7,8,9,6,35
接下来将5与62进行比较 由于满足5<62,所以此时不会进行排序
接下来将62与7进行比较 由于62>7 ,所以交换,此时4,5,7,62,2,7,8,9,6,35
······
最后为4,5,7,2,7,8,9,6,35,62
此时我们找到了最大的数,并且把它放在了最后一位,下一次遍历排序的时候就不需要动最后一位
下一次遍历会把第二大的数32排序到倒数第二位
下一次会把第三大的数9排序到倒数第三位
······
最后会把第二小的数排序到第二位
排序结束;
接下来是代码演示
首先定义一个数组,可以用输入的形式,也可以初始化,这里我们选择初始化
并建立一个函数(bubble_sort)实现冒泡排序
记录数组元素个数,与首元素地址一并传入函数中
接下来实现函数部分
我们需要遍历10次 ,每次把得到的最大数排到最后一位(去除已经拍过的位置)
然后进行比较,交换
void bubble_sort(int* a,int sz){ for (int i = 0; i < sz; i++) { //一趟冒泡排序 for (int j=0;j<sz-i-1;j++){//操作下标与交换几次 //第一趟需要交换10-1次 //第二趟需要交换10-2次 //这里i从0开始因此第i次需要交换10-i-1次 if(a[j]>a[j+1]){ int tmp = a[j]; a[j]=a[j+1]; a[j+1]=tmp; } } } }
此时加上打印数组,整段代码为
#include <stdio.h> void bubble_sort(int* a,int sz){ for (int i = 0; i < sz; i++) { //一趟冒泡排序 for (int j=0;j<sz-i-1;j++){//操作下标与交换几次 //第一趟需要交换10-1次 //第二趟需要交换10-2次 //这里i从0开始因此第i次需要交换10-i-1次 if(a[j]>a[j+1]){ int tmp = a[j]; a[j]=a[j+1]; a[j+1]=tmp; } } } } int main(){ int a[10]={5,4,62,7,2,7,8,9,6,35}; int sz = sizeof (a)/ sizeof(a[0]); bubble_sort(a,sz); for (int i = 0; i < sz; i++) { printf("%d ",a[i]); } return 0; }
打印结果为:
代码优化
如果在第1次 第二次就已经实现排序了,但循环还是会继续进行,这会导致多出来的循环导致时间过长
因此我们可以优化代码
#include <stdio.h> void bubble_sort(int* a,int sz){ for (int i = 0; i < sz; i++) { //一趟冒泡排序 int flag=1;//假设已经排序成功 for (int j=0;j<sz-i-1;j++){//操作下标与交换几次 if(a[j]>a[j+1]){ flag=0;//发生交换就说明无序 int tmp = a[j]; a[j]=a[j+1]; a[j+1]=tmp; } } if(flag==1) break; } } int main(){ int a[10]={5,4,62,7,2,7,8,9,6,35}; int sz = sizeof (a)/ sizeof(a[0]); bubble_sort(a,sz); for (int i = 0; i < sz; i++) { printf("%d ",a[i]); } return 0; }
用flag判断有无完全排序可以节省不必要的时间消耗