目录
1.冒泡排序(Bubble Sort)思想
通过对数组从前向后,依次对相邻两个元素的值进行两两比较,若发现前一个数字比后一个数字大则交换,使值较大的元素逐渐从前移向后部,就如果水底下的气泡一样逐渐向上冒。
2.示例
数组为[6,9,36,34,26,12,27,12]
可观看这个视频
冒泡排序演示
总结
1.一共进行了n次循环遍历
2.比较的次数随着循环轮次增多而减少
3.当数组有序的时候可以提前终止(优化)
3.示例代码
void BubbleSort(int* arr, int n)
{
//1.数组为空或者数组长度为0,1不需要排序
if (arr == nullptr || n <= 1)
return;
//2.排序
for (int i = 0; i < n; i++)//一共要遍历n次,外层循环控制
{
//内层循环控制比大小和交换
for (int j = 0; j < n - 1 - i; j++)//第一次为 0到n-2下标与后一个数比较,所以为n-1-i
{
if (arr[j] > arr[j + 1])
swap(arr[j], arr[j + 1]);
}
}
}
注意内层循环的控制条件,如果少了-1,会导致数组越界访问,没有i导致无效比较次数增多
3.1优化
由冒泡排序的步骤我们知道,如果一个数组已经有序了,不会发生比较
利用这个特点我们可以设置一个标志位,用于判断是否发生交换
如果整个过程没有发生交换,直接break跳出即可
优化代码
void BubbleSort(int* arr, int n)
{
//1.数组为空或者数组长度为0,1不需要排序
if (arr == nullptr || n <= 1)
return;
//2.排序
for (int i = 0; i < n; i++)//一共要遍历n次,外层循环控制
{
bool flag = false;//表示没有发生过交换
//内层循环控制比大小和交换
for (int j = 0; j < n - 1 - i; j++)//第一次为 0到n-2下标与后一个数比较,所以为n-1-i
{
if (arr[j] > arr[j + 1])
{
swap(arr[j], arr[j + 1]);
flag = true;
}
}
if (flag)//这次循环没有发生交换,数组有序
break;
}
}
4.冒泡排序特点
4.1时间复杂度
由示例中的总结可知,时间复杂度位O(N^2)
4.2空间复杂度
只用了常量的额外变量.空间复杂度位O(1)
4.3稳定性
只有当前一个元素比后一个元素大的时候才会交换,当两个相同元素在一起的时候,不会发生交换,不会改变其顺序,所以冒泡排序是稳定的
5.简单测试
测试代码
void BubbleSort(int* arr, int n)
{
//1.数组为空或者数组长度为0,1不需要排序
if (arr == nullptr || n <= 1)
return;
//2.排序
for (int i = 0; i < n; i++)//一共要遍历n次,外层循环控制
{
bool flag = false;//表示没有发生过交换
//内层循环控制比大小和交换
for (int j = 0; j < n - 1 - i; j++)
{
if (arr[j] > arr[j + 1])
{
swap(arr[j], arr[j + 1]);
flag = true;
}
}
if (!flag)//这次循环没有发生交换,数组有序
break;
}
}
int main()
{
int arr[] = { 6,9,36,34,26,12,27,12 };
int len = sizeof(arr) / sizeof(arr[0]);//求数组长度
BubbleSort(arr, len);
for (int i = 0; i < len; i++)//打印数组看是否成功排序
{
cout << arr[i] << " ";
}
cout << endl;
return 0;
}
运行结果