前言
对于初学者而言,冒泡排序是最简单,最好记的排序方式,那么下面我会为小伙伴们简单讲解下冒泡排序的原理以及思想
代码部分
#include<stdio.h>
int main()
{
//排序思想:相邻元素比较,满足条件则交换
int arr[] = { 2,0,8,9,4,1,3,6,7,5 };
int k = 0;
int l = 0;
for (int i = 0; i < 10 - 1; i++)
{
k = 0;
for (int j = 0; j < 10 - 1 - i; j++)
{
if (arr[j] > arr[j + 1])
{
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
k = k + 1;
}
l = l + 1;//另一个计数器,不用在意,如果需要请自己调用输出
}
if (k == 0)
break;
}
return 0;
}
排序思想
相邻元素比较,满足条件则交换
代码讲解
首先我们先定义一个含有乱序数字的数组
int arr[] = { 2,0,8,9,4,1,3,6,7,5 };
然后我们要考虑,既然思想是相邻元素比较,那么肯定需要数组两个元素比较,那么我们以升序为例(即从小到大排列)那么如果前一个元素大于后一个元素,我们则进行两元素交换。
此时我们会发现我们需要不止一次交换,那么我们需要遍历数组,分别前后两元素遍历,我们通常选择双层for循环嵌套,这样我们可以保证前后需要比较的元素位置差一直是1
for (int i = 0; i < 10 - 1; i++)
{
for (int j = 0; j < 10 - 1 - i; j++)
{
如上例,i,j是我们记录需要比较的前后两元素的数组下标的工具
i 的判断条件为n -1(n代表数组有多少元素),因为我们一轮比较有时肯定是无法完整排序的,所以我们进行多轮,基于 i 值来规定就比如我们上述数组含有10个元素,那么下标从0-9,正好十轮,也就是说我们每一轮(即 i 值的变化过程)会排好一个元素的位置
j 的判断条件基于 i 值来表示两个前后元素,排好序的元素越多我们所需要比较的轮数越少,所以j的判断条件为n - 1 - i
可以画一个图来表示
(潦草.jpg)
我们会发现这里每个元素排到对应位置好之后,对应i只进行了四轮,多余一轮则会正常进行比较,但不会再交换了,会浪费时间,这里就需要之后的优化过程,后文会进行优化。
由于是升序所以判断条件就是
if (arr[j] > arr[j + 1])
那么交换的代码就是最简单的建立临时变量替换
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
如果简洁一些可以不用创建临时变量,可以使用异或运算符' ^ '
arr[j] = arr[j] ^ arr[j + 1];
arr[j + 1] = arr[j + 1] ^ arr[j];
arr[j] = arr[j] ^ arr[j + 1];
至于异或运算的具体过程不会在这里细讲,未来文章会一一解答(挖坑ing)
至此在没有优化情况下的冒泡排序法,已经写完,对于大多数初学者小伙伴来讲已经足够用了
代码优化
对于冒泡排序的优化有很多,这里我只讲如何消除多余的排序轮次,我们需要建立一个新的变量来充当计数器,每一轮重置计数器为0,在第二层循环里来计数,如果进行if里的语句即代表进行了交换操作,那么我们计数器计的数就是交换了多少次,如果我们发现从某一轮开始数据已经排好序了,那么计数器的值就不会计数,仍然为零,此时我们来检测计数器是否为0,如果是0那么我们就退出循环,以防多余轮次占用时间,如果不为0那么继续进行排序,详情参照最开始的代码部分,以上是一种比较好理解的优化方式,至于其他方式优化,依然会等到未来进行讲解,过分深入只会显得更加复杂AwA...
后记
点赞收藏关注!!!!!(大列巴尖叫.jpg)