冒泡排序
前置学习
了解排序的基本概念
点击传送门
原理
冒泡排序(Bubble Sort)排列的序列,较大(或较小)的数据会“浮”到序列的顶端(或底部)。
冒泡排序原则:
比较两个相邻的数组元素,使起满足条件交换元素位置,直到n-1轮循环操作结束。
实现
- 从头部开始,比较相邻的两个元素arr[j]和arr[j+1],如果前一个元素比后一个元素大,进行数据交换。
- 下标向后移动,即使j=j+1,再次比较元素arr[j]和arr[j+1],判断是否需要交换数据。
- 针对序列中每一对两两相邻的数据重复以上步骤,直到下标指向最后一个位置。
- 在每一轮循环中重复以上步骤(1)(2)(3),直到n-1轮循环执行完毕。
代码
//定义数组
int arr[10] = { 9,1,5,6,10,8,3,7,2,4 };
//数组元素个数
int len = sizeof(arr)/sizeof(arr[0]);
//外层控制行 表示执行次数
for (int i = 0; i < len - 1; i++)
{
//内层控制列 表示比较次数
for (int j = 0; j < len - 1 - i; j++)
{
//比较数据
if (arr[j] > arr[j + 1])
{
//交换数据
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
优化
假定外层循环执行n次(n<元素个数),数组中数据元素已经变成有序数据,则循环可以退出。
可使用flag标志位记录是否可以终止循环。
//定义数组
int arr[10] = { 9,1,5,6,10,8,3,7,2,4 };
//数组元素个数
int len = sizeof(arr)/sizeof(arr[0]);
//设置标志位
int flag = 1;
//外层控制行 表示执行次数 将flag标志位作为循环判断条件
for (int i = 0; i < len - 1 && flag; i++)
{
//如果没有进入if判断 表示数据有序,可以终止循环
flag = 0;
//内层控制列 表示比较次数
for (int j = 0; j < len - 1 - i; j++)
{
//比较数据
if (arr[j] > arr[j + 1])
{
//表示数据可以继续进行交换
flag = 1;
//交换数据
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
复杂度分析
时间复杂度:
平均时间复杂度:O(n²)
最好时间复杂度:O(n) 数组中数据有序,遍历一次,不需要交换。
最坏时间复杂度:O(n²)
空间复杂度:
O(1),只需要一个额外空间用于交换。
稳定性:
稳定排序