一分钟了解:Java 冒泡排序算法

news2024/12/31 7:39:26

1. 冒泡排序算法介绍

冒泡排序是最简单的排序算法,如果相邻元素的顺序错误,则通过反复交换相邻元素来工作。Java 中的冒泡排序不是对数组进行排序的最佳方法,但却是最基本的实现之一。在本文中,我们将学习如何用 Java 编写冒泡排序程序。

2. 冒泡排序算法原理

冒泡排序算法是重复地遍历要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。重复进行直到没有再需要交换的元素,这意味着数列已经排序完成。

冒泡排序算法适用于小型数据集,对大型数据集排序性能较差,不建议使用!

以下是 Java 中使用冒泡排序按升序对数组进行排序的算法:

    void bubbleSort(int arr[]) 
    { 
        int n = arr.length; 
        for (int i = 0; i < n - 1; i++) 
            for (int j = 0; j < n - i - 1; j++) 
                if (arr[j] > arr[j + 1]) { 
                    // 交换 temp and arr[i] 
                    int temp = arr[j]; 
                    arr[j] = arr[j + 1]; 
                    arr[j + 1] = temp; 
                } 
    } 
  1. 从数组的第一个元素开始,依次比较相邻的两个元素。
  2. 如果前一个元素大于后一个元素,交换它们的位置。
  3. 继续比较下一对相邻元素,直到最后一个元素。
  4. 重复以上步骤,每一轮比较都会将最大的元素"冒泡"到最后面。
  5. 当比较结束时,此时数组已经排好序,排序结束。

3. 冒泡排序示例

3.1 第一步

比较相邻的元素。如果第一个比第二个大(即,按照升序排序),就交换它们两个。

给定数组: [ 8,7,5,2] ,从 pos=1 遍历到 pos=4 ,如果该数字小于前一个元素,则将该数字与前一个元素交换。

 

3.2 第二步

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

对 pos=1 至 pos=3 重复上一步

 

3.3 第三步

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

按照步骤 1 将 pos=1 改为 pos=2

 

3.4 第四步

持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数需要比较。

因为现在 pos=1 到 pos=1 意味着数组现在已完全排序

 

4. Java 中的冒泡排序程序

下面是用 Java 实现冒泡排序的程序

// Java program for implementation 
// of Bubble Sort 
class BubbleSort { 
	void bubbleSort(int arr[]) 
	{ 
		int n = arr.length; 
		for (int i = 0; i < n - 1; i++) 
			for (int j = 0; j < n - i - 1; j++) 
				if (arr[j] > arr[j + 1]) { 
					// swap temp and arr[i] 
					int temp = arr[j]; 
					arr[j] = arr[j + 1]; 
					arr[j + 1] = temp; 
				} 
	} 

	// Prints the array 
	void printArray(int arr[]) 
	{ 
		int n = arr.length; 
		for (int i = 0; i < n; ++i) 
			System.out.print(arr[i] + " "); 
		System.out.println(); 
	} 

	// Driver method to test above 
	public static void main(String args[]) 
	{ 
		BubbleSort ob = new BubbleSort(); 
		int arr[] = { 64, 34, 25, 12, 22, 11, 90 }; 
		ob.bubbleSort(arr); 
		System.out.println("Sorted array"); 
		ob.printArray(arr); 
	} 
}
输出
排序数组
11 12 22 25 34 64 90

4.1 冒泡排序的复杂性和稳定性分析

时间复杂度分析:在最坏的情况下,冒泡排序需要进行n-1轮比较,每轮比较需要进行n-i次。因此,总的比较次数为(n-1) + (n-2) + … + 2 + 1 = n(n-1)/2,近似为O(n2)


空间复杂度分析:使用了常数个变量,因此空间复杂度为O(1)。

4.2 稳定性分析

什么是稳定性
        答:稳定性指的是相同的数据所在的位置经过排序后是否发生变化。换句话说就是大小相同的两个值在排序之前和排序之后的先后顺序不变,这就是稳定的。

        稳定性分析:冒泡排序将小的元素往前调或者把大的元素往后调;比较的是相邻的两个元素,交换也发生在这两个元素之间;因为相等的元素不会进行交换,所以稳定。

4.3 冒泡排序的优点

尽管冒泡排序有点慢,但它也具有某些优点,如下所示:

  • 易于实施和理解。
  • 由于不需要额外的内存,该算法的空间复杂度为 O(1)。
  • 它是一种稳定的排序算法,这意味着具有相同键值的元素在排序输出中保持其相对顺序。

5. 冒泡排序算法性能优化

既然冒泡排序算法存在巨大的性能开销,那么如何优化它呢?

在Java中,冒泡排序算法的优化主要是减少不必要的比较和交换。以下是优化的步骤:

  1. 引入一个标记,如果在一次遍历中没有发生交换,则说明数组已经排序好了,可以直接退出循环。

  2. 使用局部变量缓存被比较的元素,减少重复的访问数组的次数。

优化后的代码示例

public class BubbleSortOptimized {
    public static void bubbleSort(int[] arr) {
        if (arr == null || arr.length == 0) {
            return;
        }
        
        boolean swapped;
        int temp;
        int length = arr.length;
        
        do {
            swapped = false;
            for (int i = 1; i < length; i++) {
                if (arr[i - 1] > arr[i]) {
                    temp = arr[i - 1];
                    arr[i - 1] = arr[i];
                    arr[i] = temp;
                    swapped = true;
                }
            }
            length--; // 每次循环后,最后一个元素必然是已排序的,下次循环不需要再比较它
        } while (swapped);
    }
    
    public static void main(String[] args) {
        int[] arr = { 4, 3, 2, 1, 5 };
        bubbleSort(arr);
        // 输出排序后的数组
        for (int i : arr) {
            System.out.print(i + " ");
        }
    }
}

在这段代码中,我们使用了swapped标记来优化算法。如果在一次遍历过程中没有发生任何交换,那么数组就已经是排序好的,因此可以提前退出循环。同时,使用局部变量temp来缓存被比较的元素,减少了数组访问的次数,从而提高了性能。

6. 总结

综上,冒泡排序是一种简单的排序算法,工作原理是通过重复遍历待排序的数列比较每对相邻元素的值,若发现顺序错误则交换它们的位置。这个过程会重复进行,直到没有需要交换的元素为止,此时数列就已经排序完成。

冒泡排序算法适用于小型数据集,对大型数据集排序性能较差,不建议使用!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2040862.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

「Pytorch」解析 nn.Embedding 词嵌入 及反推输入

在Pytorch里面有三种编码方式&#xff0c;Embedding 就是其中之一&#xff0c;不同于 one_hot 需要用同长度的张量存 Embedding将单词映射为稠密向量&#xff0c;并且指定 embedding_dim维度。通过 Embedding层 转换的数据并不是经过词典映射的&#xff0c;而是原始数据。Embed…

VirtualBox扩容VDI虚拟磁盘

环境 虚拟机软件&#xff1a;VirtualBox虚拟机&#xff1a;Ubuntu 18.04.1 第一步&#xff1a;调整虚磁盘大小 方法1&#xff1a;使用VirtualBox管理器直接修改 关闭虚拟机&#xff0c;点击VirtualBox管理器菜单管理>虚拟介质管理&#xff0c;重新设大小 方法2&#x…

【Linux基础】对Linux权限的理解与管理

目录 &#x1f680;前言一&#xff0c;有关用户二&#xff0c;Linux权限管理1. 文件访问者的分类(人)2. 文件类型和访问权限(事物属性)2.1 文件类型2.2 文件/目录的基本权限 三&#xff0c;文件权限值的表示方法3.1 字符表示方法3.2 八进制数值表示方法 四&#xff0c;文件访问…

服务器是什么?怎么选择适合自己的服务器?

在这个数字化的世界中&#xff0c;我们每天都在与各种网站打交道&#xff0c;浏览新闻、购物、看视频等。你是否曾经好奇过&#xff0c;这些网站是如何运行的&#xff1f;它们又是如何实现随时随地可访问的呢&#xff1f; 在这背后&#xff0c;有一个神秘的角色在默默地支撑着…

数据结构与算法 - 贪心算法

一、贪心例子 贪心算法或贪婪算法的核心思想是&#xff1a; 1. 将寻找最优解的问题分为若干个步骤 2. 每一步骤都采用贪心原则&#xff0c;选取当前最优解 3. 因为没有考虑所有可能&#xff0c;局部最优的堆叠不一定让最终解最优 贪心算法是一种在每一步选择中都采取在当前…

letcode 分类练习 树的遍历

letcode 分类练习 树的遍历 树的构建递归遍历前序遍历中序遍历后序遍历 迭代遍历前序遍历中序遍历后序遍历 层序遍历层序遍历可以解决的问题107. 二叉树的层序遍历 II199. 二叉树的右视图637. 二叉树的层平均值429. N 叉树的层序遍历515.在每个树行中找最大值116.填充每个节点的…

掌机系统MuOS游戏名称中文乱码解决主题

最近买了安伯尼克的rg35xxh掌机来玩儿&#xff0c;然后刷了muos&#xff0c;系统很小巧&#xff0c;1g的运行内存&#xff0c;系统运行的时候只占用了不到100m&#xff0c;而且界面也很美观&#xff0c;就是有一个问题——中文名称会乱码&#xff0c;都变成了方框&#xff0c;从…

如何给IP地址开启https—IP证书

先IP地址申请的前提&#xff1a;80端口有打开&#xff0c;或者可以短暂的打开10分钟左右等验证完IP管理权再关掉。 一&#xff1a;访问JoySSL官网&#xff0c;注册账号并填写注册码230922&#xff0c;选择IP地址证书并下单加入购物车&#xff0c;下单之后就会跳转到证书申请界…

Linux--应用层协议HTTP协议(http服务器构建)

目录 1.HTTP 协议 2.认识 URL 3.urlencode 和 urldecode&#xff08;编码&#xff09; urlencode&#xff08;URL编码&#xff09; urldecode&#xff08;URL解码&#xff09; 4.HTTP 协议请求与响应格式 4.1HTTP 常见方法&#xff08;三种&#xff09; 5.HTTP 的状态码…

C++:命名空间与输入输出

目录 前言 一、命名空间 1.1 namespace的价值 1.2 namespace的定义 1.3 命名空间的使用 二、C输入&输出 前言 C是一种面向对象的计算机程序设计语言&#xff0c;‌它扩展了C语言的功能&#xff0c;‌并引入了面向对象编程的概念&#xff0c;‌如类、‌继承和多态等&a…

【笔记】从零开始做一个精灵龙女-画贴图阶段(下)

补充四点&#xff0c;第一&#xff0c;前期画体积用一号或十三号笔刷&#xff0c;压力60&#xff0c;硬度80&#xff0c;体积大一点 2号笔刷比较适合画过渡和软一点的东东 第二&#xff0c; 游戏里面角色原画海报都是发光很亮很透。但是在bp不能画那么亮&#xff0c;因为你进…

git强制推送代码教程

git强制推送代码教程 首先说明情况&#xff0c;我的代码remote了两个git库&#xff0c;现在想要推送到其中一个&#xff0c;但是版本不对&#xff0c;被拒绝&#xff0c;因此下面将进行强制推送 首先检查远程库都有哪些 git remote -v2. 检查当前的分支 git branch当前分支前…

Python 初学者入门:揭秘 Anaconda

初学者在学习 Python 时&#xff0c;经常看到的一个名字是 Anaconda。究竟什么是 Anaconda&#xff0c;为什么它如此受欢迎&#xff1f;在这篇文章中&#xff0c;我们将探讨 Anaconda &#xff0c;了解 Anaconda 的从安装到使用的。 Anaconda 是一个免费开源的 Python 和 R 编…

PCL 三线性插值

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 三线性插值是一种在三维空间中使用已知数据点进行插值的方法。它是在立方体内的插值方法,通过利用立方体的八个顶点的已知值来估算立方体内任意一点的值。三线性插值扩展了一维的线性插值和二维的双线性插值。其基…

数据结构入门——06树

1.树 树&#xff08;Tree&#xff09;非线性数据结构&#xff0c;它是n&#xff08;n≥0&#xff09;个节点的有限集合&#xff0c;它满足两个条件 &#xff1a; 有且仅有一个特定的称为根&#xff08;Root&#xff09;的节点&#xff1b; 其余的节点可以分为m&#xff08;m…

一文带你快速了解——keepalived高可用集群

一、高可用集群 1.1 集群类型 LB&#xff1a;Load Balance 负载均衡LVS/HAProxy/nginx&#xff08;http/upstream, stream/upstream&#xff09;HA&#xff1a;High Availability 高可用集群 数据库、RedisSPoF: Single Point of Failure&#xff0c;解决单点故障HPC&#xf…

Java_finalize

目录 finalize方法 案例演示 finalize方法 当垃圾回收器确定不存在对该对象的更多引用时&#xff0c;由对象的垃圾回收器调用此方法。 当对象被回收时&#xff0c;会自动调用&#xff0c;子类可以重写该方法&#xff0c;做一些释放资源的操作。 案例演示 可以使用快捷键进行…

一台电脑同时开多个微信

这几天闲没事&#xff0c; 就在网上查了一些相关的一台电脑同时开多个微信。经测试&#xff0c;确实可以做的&#xff0c;而且一点了不麻烦。经本人测试&#xff0c;把信息补全一些... 同时登录了两个微信&#xff0c;为什么只能两个微信&#xff0c;因为我只有两个微信。废话少…

leetcode412. Fizz Buzz,简单遍历

leetcode412. Fizz Buzz 给你一个整数 n &#xff0c;找出从 1 到 n 各个整数的 Fizz Buzz 表示&#xff0c;并用字符串数组 answer&#xff08;下标从 1 开始&#xff09;返回结果&#xff0c;其中&#xff1a; answer[i] “FizzBuzz” 如果 i 同时是 3 和 5 的倍数。 answ…