没有人天生是王者,就看谁熬得过去。
冒泡排序概念:
简而言之,冒泡排序(bubbleSort)就是对两个相邻的关键字进行顺序比对,如果顺序则不变,如果反序则交换,直到没有反序的关键字记录为止。
注意:
- 两个相邻的关键字比较,如:3、5、1、8、2
3和5比较,3比较5小,不交换顺序,之后是5和1比较而不是3和1比较; - 如果有n个元素,则需要比较n-1次,每一轮比较都会减少一次。n个元素总共需要(n-1)(n-2)(n-3)…321次对比;
冒泡排序的特点:
升序排序中每一轮比较会把最大的数下沉到最底,所以相互比较的次数都会比前一轮少一次,
排序流程:
假设给出这样一串数字:
32 87 60 44 93 37 65 18 29
第一趟冒泡排序:
32与87比较,32<87,不交换: 32 87 60 44 93 37 65 18 29
87与60比较,87>60,交换: 32 60 87 44 93 37 65 18 29
87与44比较,87>44,交换: 32 60 44 87 93 37 65 18 29
87与93比较,87<93,不交换: 32 60 44 87 93 37 65 18 29
93与37比较,93>37,交换: 32 60 44 87 37 93 65 18 29
93与65比较,93>65,交换: 32 60 44 87 37 65 93 18 29
93与18比较,93>18,交换: 32 60 44 87 37 65 18 93 29
93与29比较,93>29,交换: 32 60 44 87 37 65 18 29 93
第一趟结束;加黑的数字就是我们交换后的结果,依次可以进行后面继续排序。
第二趟冒泡排序:
32 60 44 87 37 65 18 29 93
32与60比较,32<60,不交换: 32 60 44 87 37 65 18 29 93
60与44比较,60>44,交换: 32 44 60 87 37 65 18 29 93
60与87比较,60<87,不交换: 32 44 60 87 37 65 18 29 93
87与37比较,87>37,交换: 32 44 60 37 87 65 18 29 93
87与65比较,87>65,交换: 32 44 60 37 65 87 18 29 93
87与18比较,87>18,交换: 32 44 60 37 65 18 87 29 93
87与29比较,87>29,交换: 32 44 60 37 65 18 29 87 93
第二趟结束;加黑的数字就是我们交换后的结果,依次可以进行后面继续排序,后面的排序和上面方法一样,将不在展示。
直到最后一趟排序过程中不发生关键字交换,算法结束。
下面我们用冒泡排序的代码执行上述过程,我将对代码注释的通俗易懂,便于更深入的理解:
#include<stdio.h>
void BubbleSort(int k[],int n) //这里默认需要排序的关键字为整型
{
int i,j,temp,count1=0,count2=0,flag; //i和j都是代表数字的位数,count为计数器,flag是表示本次排序是否发生变化的标志
for(i=0;i<n-1;i++) //外层循环
{
for(j=0;j<n-i-1;j++) //内层循环
{
count1++; //对比较次数进行计数
if(k[j] > k[j+1]) //开始比较大小
{
flag = 1; //flag为1则表示本论排序发生变化
count2++; //对移动次数进行计数
temp = k[j]; //互换位置
k[j] = k[j+1];
k[j+1] = temp;
}
flag = 0; //排序不发生变化则flag为0
}
}
printf("总共进行了%d次比较,进行了%d次移动!\n",count1,count2);
}
int main()
{
int i,k[9] = {32,87,60,44,93,37,65,18,29};
BubbleSort(k,9);
printf("排序后的结果是: ");
for(i=0;i<9;i++)
{
printf("%3d \0",k[i]);
}
printf("\n");
return 0;
运行结果:
冒泡排序的时间复杂度和空间复杂度以及稳定性:
算法类别 | 平均时间复杂度 | 最坏时间复杂度 | 最好时间复杂度 | 空间复杂度 | 稳定性 |
---|---|---|---|---|---|
冒泡排序 | n2 | n2 | n | 1 | 稳定 |