冒泡排序详解(Bubble Sort)

简介: 冒泡排序详解

一、简单释义

1、算法概念

 冒泡排序(Bubble Sort)是重复地走访过要排序的元素列,依次比较两个相邻的元素,如果顺序(如从大到小、首字母从Z到A)错误就把他们交换过来。走访元素的工作是重复地进行,直到没有相邻元素需要交换,也就是说该元素列已经排序完成。

2、算法目的

 把无序数组通过通过两两相比交换位置,最后形成一个有序数组  (文中以升序为例)

3、算法思想

 通过不断比较相邻的元素,如果左边的元素 大于 右边的元素,则进行交换,直到所有相邻元素都保持升序,则算法结束。

4、算法由来

 这个算法的名字由来是因为越小的元素会经由交换慢慢浮动到数列的顶端(升序或降序排列),就如同碳酸饮料中二氧化碳的气泡最终会上浮到顶端一样,故名“冒泡排序”。

二、核心思想

「迭代」:类似的事情,不停地做。

「比较」:关系运算符 大于(>) 的运用。

「交换」:变量或者对象的值的互换。

三、图形展示

1、宏观展示

8216aad0a6e445589e8e9fdcab74be4d.png

2、微观展示

 以3、6、4、2、11、10、5这个数组为例,由于每一趟排序的过程都是一样的。所以下面是第一趟排序的详细比较过程

9d9b4cc8a05743ed8b78a81e4be9fd54.png

 1、第一次比较:3与6进行比较,3 < 6 所以不交换位置。得到3,6,4,2,11,10,5

790a061339bc4012ae5a92707c281062.png

 2、第二次排序:6与4比较,6 > 4,6与4交换位置,如果相邻的元素逆序就交换。得到3,4,6,2,11,10,5

4889142aa1b24cd9b22fffd8abfbea66.png

 3、第三次排序:交换完位置后两个索引又同时移动让 6 与 2比较,6 > 2,6与2交换位置。得到3,4,2,6,11,10,5

e96c28439a9e4e28a3e036d5f6296ead.png

 4、第四次排序:6与11进行比较,6 < 11 所以不交换位置。得到 3,4,2,6,11,10,5

164051d749124b2680fff00ddaf7b595.png

 5、第五次排序:11与10进行比较,11 > 10 所以进行位置交换。得到 3,4,2,6,10,11,5

0a5c56d08391455eb904df164a247341.png

 6、最后将11与5进行比较,11 > 5 所以进行位置交换。得到3,4,2,6,10,5,11

四、算法实现

1、实现思路

 将图形化展示的过程转换成对应的开发语言,本文中主要以Java语言为例来进行算法的实现。

 1. 比较相邻的元素。如果第一个比第二个大,就交换它们两个;

 2. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数;

 3. 针对所有的元素重复以上的步骤,除了最后一个;

 4. 重复步骤1~3,直到排序完成。

 能把整个过程描述清楚实现起来才会更加容易!!!

2、代码实现

/**
 * @BelongsProject: demo
 * @BelongsPackage: com.wzl.Algorithm.BubbleSort
 * @Author: Wuzilong
 * @Description: 冒泡排序
 * @CreateTime: 2023-05-01 11:18
 * @Version: 1.0
 */
public class BubbleSort {
    public static void main(String[] args) {
        int[] numArray={3,6,4,2,11,10,5};
        //冒泡排序的时间复杂度为O(n*n)
        int temp = 0;//临时变量
        for (int j = 0; j < numArray.length - 1; j++) {
            for (int i = 0; i < numArray.length-1 -j ; i++) {
                if (numArray[i] > numArray[i+1]){
                    //三角交换
                    temp = numArray[i];
                    numArray[i] = numArray[i+1];
                    numArray[i+1] = temp;
                }
            }
            System.out.println("第"+(j+1)+"趟"+Arrays.toString(numArray));
        }
    }
}

3、运行结果

6fa5a9edec084b4787993fc930f5a0c5.png

4、代码优化

会存在数组在中间的某一趟中就已经是有序的了,减少后面的无效比较

/**
 * @BelongsProject: demo
 * @BelongsPackage: com.wzl.Algorithm.BubbleSort
 * @Author: Wuzilong
 * @Description: 冒泡排序优化
 * @CreateTime: 2023-05-01 11:18
 * @Version: 1.0
 */
public class BubbleSort {
    public static void main(String[] args) {
        int[] numArray={3,6,4,2,11,10,5};
        int temp = 0;//临时变量
        boolean flag = false;//用于优化冒泡排序,判断是否进行过交换
        for (int j = 0; j < numArray.length - 1; j++) {
            for (int i = 0; i < numArray.length-1 -j ; i++) {
                if (numArray[i] > numArray[i+1]){
                    //三角交换
                    temp = numArray[i];
                    numArray[i] = numArray[i+1];
                    numArray[i+1] = temp;
                    flag = true;
                }
            }
            System.out.println("第"+(j+1)+"趟"+Arrays.toString(numArray));
            //如果没有进入三角交换则证明数组已经有序,直接退出循环即可
            //如果进入了三角交换,把flag赋值为false,来判断下一次循环是否进入三角交换
            if (flag == false){
                break;
            }else {
                flag = false;
            }
        }
    }
}

5、运行结果

8c4888464ec44754aa3a18f697269c91.png

五、算法描述

1、问题描述

 给定一个 n 个元素的数组,数组下标从 0 开始,采用冒泡排序将数组按照升序排列。

2、算法过程

整个算法过程分为以下几步:

 1) 循环迭代变量 i = 0 → n − 1 i = 0 \to n-1i=0→n−1;

 2) 每次迭代,令 j = i ,循环执行比较 a [ j ]和 a [ j + 1 ] ,如果产生 a [ j ] > a [ j + 1 ] 则交换两者的值。然后执行 j = j + 1 ,这时候对 j 进行判断,如果 j ≥ n − 1 ,则回到 1),否则继续执行 2)。

3、算法总结

 冒泡排序虽然时间复杂度比较高,但是它的实现简单 ,代码易于理解。在实际应用中,冒泡排序常常被用作教学和理论分析的基础算法, 或者用于数据量较小 的排序任务。对于数据量较大的排序任务,我们通常会选择更高效的排序算法来完成。

六、算法分析

1、时间复杂度

 最好的时间复杂度是O(n):是开始就已经有序了,那么就可以不用交换元素了,只需要1次冒泡。

 最坏的时间复杂度为O(n^2):也就是开始的时候元素是逆序的,那么每一次排序都要交换两个元素。

2、空间复杂度

 冒泡排序只需要常数级别的额外空间来存储临时变量,因此空间复杂度为 O(1)。

3、算法稳定性

 冒泡排序是一种稳定的排序算法,因为在比较相邻的元素时,只有在它们的顺序不正确时才会交换它们,因此相同元素的顺序不会被改变。


相关文章
|
1月前
|
搜索推荐
冒泡排序(Bubble Sort)以及选择排序(Selection Sort)和快速排序(Quick Sort)详细解析
冒泡排序(Bubble Sort)以及选择排序(Selection Sort)和快速排序(Quick Sort)详细解析
18 1
|
6月前
|
搜索推荐 算法 Java
sort-01-bubble sort 冒泡排序算法详解
这是一个关于排序算法的系列文章摘要。作者整理了10种不同的排序算法,包括冒泡排序、快速排序、选择排序、堆排序、插入排序、希尔排序、归并排序、计数排序、桶排序和大文件外部排序。文章详细介绍了冒泡排序的工作原理、流程,并提供了代码实现,强调了在实现中考虑的改进点,如统一接口、实用性增强和日志输出。此外,还提供了一个排序接口和工具类以方便使用,并通过测试代码和日志展示了排序过程。整个系列旨在帮助读者理解和掌握排序算法。相关代码已开源在GitHub。
|
6月前
|
搜索推荐 算法 Java
sort-03-SelectSort 选择排序算法详解
这是一个关于排序算法的系列文章摘要,包括了各种排序算法的介绍和Java实现。文章列举了冒泡排序、快速排序、选择排序、堆排序、插入排序、希尔排序、归并排序、计数排序、桶排序以及大文件外部排序的链接和简要说明。其中,选择排序算法被详细解释,它是通过找到未排序序列中的最小元素并将其放到正确位置来逐步构建有序序列的。Java实现中,选择排序的`doSort`方法通过两层循环实现,时间复杂度为`O(N^2)`,是稳定的排序算法。整个排序项目已开源在GitHub。
|
6月前
|
算法 搜索推荐
Bubble Sort
Bubble Sort“【5月更文挑战第19天】”
39 0
|
6月前
|
搜索推荐 算法 Java
sort-02-QuickSort 快速排序到底快在哪里?
这是一个关于排序算法的系列文章的摘要。文章详细介绍了各种排序算法,包括冒泡排序、快速排序、选择排序、堆排序、插入排序、希尔排序、归并排序、计数排序、桶排序以及处理大文件的外部排序。特别强调了快速排序,它是1959年由Tony Hoare发明的,平均时间复杂度为O(n log n),优于其他如合并排序和堆排序。快速排序采用分而治之的策略,选取基准元素,通过分区操作将数组分成两部分,然后递归地对这两部分进行排序。文章还通过示例和Java代码解释了快速排序的步骤和实现。最后,提供了开源项目的链接,供读者进一步学习和研究。
|
6月前
|
搜索推荐 算法 Java
sort-08-counting sort 计数排序
这是一个关于排序算法的系列文章摘要。文章详细介绍了多种排序算法,包括冒泡排序、快速排序、选择排序、堆排序、插入排序、希尔排序、归并排序、计数排序、桶排序以及大文件外部排序。计数排序是一种线性时间复杂度的稳定排序算法,由 Harold H. Seward 在1954年提出。基础版计数排序通过创建一个与最大元素等长的新数组来统计每个元素出现的次数,然后填充排序结果。改良版则考虑了空间浪费问题,通过找出最小值来减少数组长度。此外,还提出了使用 TreeMap 来扩展排序算法以适应非数字元素的情况。
2-路插入排序(Two-Way Insertion Sort)
算法介绍 算法描述 算法分析 代码实现 参考
|
搜索推荐 算法 数据可视化
【基础篇】9 # 排序:冒泡排序(Bubble Sort)、插入排序(Insertion Sort)、选择排序(Selection Sort)
【基础篇】9 # 排序:冒泡排序(Bubble Sort)、插入排序(Insertion Sort)、选择排序(Selection Sort)
113 0
【基础篇】9 # 排序:冒泡排序(Bubble Sort)、插入排序(Insertion Sort)、选择排序(Selection Sort)
|
搜索推荐 C语言
快排函数 -- qsort函数(Quick Sort)
快排函数 -- qsort函数(Quick Sort)
128 0
|
算法 Java 测试技术
详解Java算法之冒泡排序(Bubble Sorting)
详解Java算法之冒泡排序(Bubble Sorting)
230 0
详解Java算法之冒泡排序(Bubble Sorting)