话不多说,我们直接开始写代码。
#include<stdio.h> int main() { int i,j; int arr[] = {20,-2,1314,5,-5,9999,0}; int sz = sizeof(arr) / sizeof(arr[0]);//获取数组的长度 //数组排序前,遍历数组 for(i = 0;i < sz;i++) { printf(" %d ",arr[i]); } //使用冒泡排序将数组中的元素从小到达依次排列 for(i = 0;i < sz;i++) { for(j = 0;j < sz - i -1;j++) { if(arr[j] > arr[j + 1]) { int temp = arr[j]; arr[j] = arr[j+1]; arr[j+1] = temp; } } } //数组排序后,遍历数组 printf("\n"); for(i = 0;i < sz;i++) { printf(" %d ",arr[i]); } return 0; }
①首先,我们定义了一个无序的整形数组arr
②我们使用了sizeof函数获取arr数组的长度//显而易见这里的数组长度为7,即sz的值为7
③使用for循环对数组遍历
④使用冒泡排序对arr数组进行操作
理解:我们在这里首先使用第一个for循环(即外层循环)是比较的轮数,数组内有7个数,那么就应该比较7-1=6轮,第二个for循环(即内层循环)比较的是当前这一轮的比较次数,例如:第一轮比较7-1=6次,第二轮比较7-2=5次,但是由于外层循环每循环一次就会将数组中的最大值放到数组的最后一个位置,所以外层循环每循环一次,内层循环可以少循环一次,所以控制第二层循环的循环条件应该是一个变量,可以用(j < sz - i - 1)表示。
我们一步步来看一下这个冒泡排序的具体过程(以此示例数组为例)
20 -2 1314 5 -5 9999 0 这是数组的默认无序的排列
进入第一次外层循环:i = 0
进入内层循环:j = 0 j < sz - i - 1(j < 6) 进入if语句 if(arr[0]>arr[1]) 即20 > -2 ? 结果为真, 所以我们定义了一个临时变量,将20与-2调换位置,此时arr[0] = -2,arr[1] = 20。语句结束 后,j++,j = 1,j < sz - i - 1(j < 6),内层循环的第 一次循环结束,进入内层循环的第二次循 环,进入if语句 if(arr[1]>arr[2]) 即20 > 1314 ? 结果为假,不执行if语句中的交换语句j++,j = 2, j < sz - i - 1(j < 6),内层循环的第二次循环结束,进入内层循环的第三次循环,进 入if语句 if(arr[2]>arr[3]) 即1314> 5 ? 结果为真,将1314与5调换位置,此时arr[2] =5, arr[3] = 1314。.................依次类推,当内层循环的执行最后一次循环当j = 5时,j < sz - i - 1(j < 6),进入if语句 if(arr[5]>arr[6]) 即9999> 0 ? 结果为真,将9999与0调换位置,此时 arr[5] =0,arr[6] = 9999。j++,j = 6,j < sz - i - 1(j < 6),不满足循环条件,退出内层循环
i++,i = 1,i < sz(i < 7)
进入第二次外层循环:
由第一次的外层循环易知,每完成一次外层循环,都会将数组中的最大值放到数组的最后,
所以每一次外层循环结束后,再次进入只需要将前sz-1-i个数组元素进行两两比较,判断是 否需要交换位置(即这个数组长度为7的数组结束第一次外层循环之后,元素9999,即数组 最大值已经交换到了数组的最后,当进入第二次外层循环只需要对前6个元素进行操作,找 到这前六个元素的最大值并将其放在数组的倒数第二个位置,所以第二次外层循环较第一 次外层的循环的内层循环要少一次,以此类推就可理解第二次for循环的循环条件 j < sz-i-1)
..............
冒泡排序的大概框架就是这样,初学者其实只要多看几遍多写几次就很好理解啦~~
最后分享一张冒泡排序的动态示意图吧,便于大家加强对冒泡循环的理解~~