冒泡排序:
我们先来介绍一下冒泡排序,冒泡排序的是基于交换类的排序算法,它主要执行的就是交换。
下面我们来演示一下排序算法的实现过程
我们这里定义一个数组,数组当中有五个元素分别是数字1-5(乱序),现在我们想对这组数据进行排序让他们从小到大排列,我们使用冒泡排序进行实现。
经过第一轮交换后我们会得到下面这样的一个数组
我们可以看到经过一轮的比较4这个数到了后面。
下面大家思考一下我们每一次比较标识符是如何变化的。
第一轮比较标识符是从下表为0到下标位3
第二轮比较标识符是从下表为0到下标位2
第三轮比较标识符是从下表为0到下标位1
第四轮比较标识符是从下表为0到下标位0
这里就有人来问了第四轮还用比较吗?我们可以看一下我们每次比较的是当前下标与后一位的大小,所以第四轮还是要进行的。(这个还不懂的可以自己手动拿笔在纸上演示一遍哈)
我们可以发现冒泡排序每一轮比较都会把最大的数放到最后面,所以说我们要排一个有n个元素的数组需要进行n-1轮。
下面我们看一下如何用C语言代码来实现冒泡排序:(我们这里使用一个函数来实现)
算法改进:
下面我们进一步思考一下当前代码,每次对传给我们的具有n个元素的数组进行排序真的需要进行n-1轮?如果传给我们的一个数组只有前面几个元素是乱序的后面的本身就有序,或者极端点传给我们的数组本身就是排好序的,此时我们用这个算法还是需要进行n-1轮的比较,这样我们这个算法的效率就大打折扣,我们如何对这个算法进行改进?
大家看一下下面这个改进版本:
上面这个改进版本与之前比较多加了一个变量g,可以看到while循环的执行条件改变了,添加了一个对g值的判断,只有当g的值为非0时并且数组长度还有效才会进行下一步,
并且在for循环中也会改变g的值,我们可以看的每次for循环当中执行交换语句都会将g赋值为1,
下面说一下这样做的作用:
我们将g的值初始化为1保证至少会进行一轮比较,进入while循环后将g赋值为0,假如for循环当中进行了交换(也就说明当前序列并未排好)我们就会将g赋值为1.用来保证下一轮比较可以进行,假如某一轮执行并未进行交换,此时说明当前数组已经排好,无需进行下一轮。While循环条件为假直接跳出循环,函数执行完成。