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

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

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. 稳定性:稳定

目录
打赏
0
0
0
0
9
分享
相关文章
C 408—《数据结构》图、查找、排序专题考点(含解析)
408考研——《数据结构》图,查找和排序专题考点选择题汇总(含解析)。
83 29
【C++数据结构——内排序】二路归并排序(头歌实践教学平台习题)【合集】
本关任务是实现二路归并算法,即将两个有序数组合并为一个有序数组。主要内容包括: - **任务描述**:实现二路归并算法。 - **相关知识**: - 二路归并算法的基本概念。 - 算法步骤:通过比较两个有序数组的元素,依次将较小的元素放入新数组中。 - 代码示例(以 C++ 为例)。 - 时间复杂度为 O(m+n),空间复杂度为 O(m+n)。 - **测试说明**:平台会对你编写的代码进行测试,提供输入和输出示例。 - **通关代码**:提供了完整的 C++ 实现代码。 - **测试结果**:展示代码运行后的排序结果。 开始你的任务吧,祝你成功!
48 10
【C++数据结构——内排序】希尔排序(头歌实践教学平台习题)【合集】
本文介绍了希尔排序算法的实现及相关知识。主要内容包括: - **任务描述**:实现希尔排序算法。 - **相关知识**: - 排序算法基础概念,如稳定性。 - 插入排序的基本思想和步骤。 - 间隔序列(增量序列)的概念及其在希尔排序中的应用。 - 算法的时间复杂度和空间复杂度分析。 - 代码实现技巧,如循环嵌套和索引计算。 - **测试说明**:提供了测试输入和输出示例,帮助验证代码正确性。 - **我的通关代码**:给出了完整的C++代码实现。 - **测试结果**:展示了代码运行的测试结果。 通过这些内容,读者可以全面了解希尔排序的原理和实现方法。
65 10
|
2月前
|
【C++数据结构——内排序】快速排序(头歌实践教学平台习题)【合集】
快速排序是一种高效的排序算法,基于分治策略。它的主要思想是通过选择一个基准元素(pivot),将数组划分成两部分。一部分的元素都小于等于基准元素,另一部分的元素都大于等于基准元素。然后对这两部分分别进行排序,最终使整个数组有序。(第一行是元素个数,第二行是待排序的原始关键字数据。本关任务:实现快速排序算法。开始你的任务吧,祝你成功!
55 7
数据结构与算法学习十三:基数排序,以空间换时间的稳定式排序,速度很快。
基数排序是一种稳定的排序算法,通过将数字按位数切割并分配到不同的桶中,以空间换时间的方式实现快速排序,但占用内存较大,不适合含有负数的数组。
68 0
数据结构与算法学习十三:基数排序,以空间换时间的稳定式排序,速度很快。
数据结构与算法学习十一:冒泡排序、选择排序、插入排序
本文介绍了冒泡排序、选择排序和插入排序三种基础排序算法的原理、实现代码和测试结果。
50 0
数据结构与算法学习十一:冒泡排序、选择排序、插入排序
【用Java学习数据结构系列】七大排序要悄咪咪的学(直接插入,希尔,归并,选择,堆排,冒泡,快排)以及计数排序(非比较排序)
【用Java学习数据结构系列】七大排序要悄咪咪的学(直接插入,希尔,归并,选择,堆排,冒泡,快排)以及计数排序(非比较排序)
48 1
【初阶数据结构】深度解析七大常见排序|掌握底层逻辑与原理(二)
【初阶数据结构】深度解析七大常见排序|掌握底层逻辑与原理
【初阶数据结构】深度解析七大常见排序|掌握底层逻辑与原理(一)
【初阶数据结构】深度解析七大常见排序|掌握底层逻辑与原理
蓝桥杯宝藏排序 | 数据结构 | 快速排序 归并排序
蓝桥杯宝藏排序 | 数据结构 | 快速排序 归并排序
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等