[数据结构 -- 手撕排序第三篇] 冒泡排序

简介: [数据结构 -- 手撕排序第三篇] 冒泡排序

1、常见的排序算法

1.1 交换排序基本思想

冒泡排序属于交换排序之一,我们先来了解以下冒泡排序思想。
基本思想:所谓交换,就是根据序列中两个记录键值的比较结果来对换这两个记录在序列中的位置,交换排序的特点是:将键值较大的记录向序列的尾部移动,键值较小的记录向序列的前部移动。


2、冒泡排序的实现

2.1 基本思想

我们本篇讲冒泡排序以排升序来举例。

基本思想:对比数组前一个数字与后一个数组的大小,当前一个数大于后一个数,我们就交换两个数字,遍历整个数组,不断判断,进行交换。


2.2 单趟排序

2.2.1 单趟排序分析

单趟排序时,第一趟排序就将最大数排到了数组尾。


2.2.2 单趟排序实现代码

for (int j = 1; j < n; j++)
{
    if (a[j - 1] > a[j])
    {
        int tmp = a[j - 1];
        a[j - 1] = a[j];
        a[j] = tmp;
    }
}

3、冒泡排序完整代码实现

3.1 思路分析

我们看到单趟排序第一趟时,就将最大值排到了数组尾部,按照这样的分析,我们排n-1趟就可以实现将整个数组完全排序。

这里为什么是 n-1 趟,当倒数第二小的数字排好序后,倒数第一小的数字自然就排好。

3.2 代码实现

void bubble_sort(int* a, int n)
{
  for (int i = 0; i < n - 1; i++)
  {
    for (int j = 1; j < n - i; j++)
    {
      if (a[j - 1] > a[j])
      {
        int tmp = a[j - 1];
        a[j - 1] = a[j];
        a[j] = tmp;
      }
    }
  }
}

4、时间复杂度

冒泡排序时间复杂度:O(N^2)。

无论是数组有序或者无序都是O(N^2),因为无论是否有序我们都需要比大小,而比大小正好是在内层循环里面,所以时间复杂度是与数组是否有序无关。

5、优化算法

5.1 优化算法思路

其实我们不难想到,如果数组是有序的,那么就不用循环那么多次了。
Q:那我们如何才能判断出数组是有序的呢?


A:其实不难,当我们数组是有序的时候就不发生交换,这就是优化算法的关键。


那么我们如何写呢?我们在内层循环外定义一个 flag = 1,假设是有序,在交换语句里我们将 flag 改为 0,当内层循环完后我们判断flag是否为1,为1就说明数组是有序的,此时就break,跳出了整个循环。

5.2 优化算法代码实现

void bubble_sort(int* a, int n)
{
  for (int i = 0; i < n - 1; i++)
  {
    int flag = 1;
    for (int j = 1; j < n - i; j++)
    {
      if (a[j - 1] > a[j])
      {
        flag = 0;
        int tmp = a[j - 1];
        a[j - 1] = a[j];
        a[j] = tmp;
      }
    }
    if (1 == flag)
      break;
  }
}

优化后最优的时间复杂度:O(N)。此时只是第一趟循环,判断是否有序。

6、冒泡排序的特性总结

1. 冒泡排序是一种非常容易理解的排序

2. 时间复杂度:O(N^2)

3. 空间复杂度:O(1)

4. 稳定性:稳定

相关文章
|
28天前
|
算法 搜索推荐 Java
数据结构与算法学习十三:基数排序,以空间换时间的稳定式排序,速度很快。
基数排序是一种稳定的排序算法,通过将数字按位数切割并分配到不同的桶中,以空间换时间的方式实现快速排序,但占用内存较大,不适合含有负数的数组。
22 0
数据结构与算法学习十三:基数排序,以空间换时间的稳定式排序,速度很快。
|
28天前
|
算法 搜索推荐
数据结构与算法学习十一:冒泡排序、选择排序、插入排序
本文介绍了冒泡排序、选择排序和插入排序三种基础排序算法的原理、实现代码和测试结果。
14 0
数据结构与算法学习十一:冒泡排序、选择排序、插入排序
|
29天前
|
存储 搜索推荐 算法
【用Java学习数据结构系列】七大排序要悄咪咪的学(直接插入,希尔,归并,选择,堆排,冒泡,快排)以及计数排序(非比较排序)
【用Java学习数据结构系列】七大排序要悄咪咪的学(直接插入,希尔,归并,选择,堆排,冒泡,快排)以及计数排序(非比较排序)
22 1
|
1月前
|
搜索推荐 索引
【初阶数据结构】深度解析七大常见排序|掌握底层逻辑与原理(二)
【初阶数据结构】深度解析七大常见排序|掌握底层逻辑与原理
|
1月前
|
搜索推荐 C++
【初阶数据结构】深度解析七大常见排序|掌握底层逻辑与原理(一)
【初阶数据结构】深度解析七大常见排序|掌握底层逻辑与原理
|
1月前
|
算法
蓝桥杯宝藏排序 | 数据结构 | 快速排序 归并排序
蓝桥杯宝藏排序 | 数据结构 | 快速排序 归并排序
05_用一个栈实现另一个栈的排序
05_用一个栈实现另一个栈的排序
|
1月前
|
人工智能 搜索推荐 算法
【初阶数据结构】深度解析七大常见排序|掌握底层逻辑与原理(三)
【初阶数据结构】深度解析七大常见排序|掌握底层逻辑与原理
|
3月前
|
C语言
数据结构——排序【上】
数据结构——排序【上】
|
3月前
|
存储 算法 搜索推荐
【初阶数据结构篇】冒泡排序和快速排序(中篇)
与直接插入排序法相比,比较次数一致,但冒泡排序的交换需要执行三次,而直接插入排序因为使用了tmp临时变量存储要插入的数据,只用执行一次,所以直接插入排序法效率明显更高。
29 1