【最基础最直观的排序 —— 冒泡排序算法】

news2024/9/23 9:15:53

最基础最直观的排序 —— 冒泡排序算法

冒泡排序(Bubble Sort)是一种计算机科学领域的较简单的排序算法,属于交换排序。其基本思想是在待排序的一组数中,将相邻的两个数进行比较,若前面的数比后面的数大就交换两数,否则不交换;如此下去,直至最终完成排序。

在冒泡排序中以升序为例,算法将待排序的 n 个数中相邻两个数进行比较,将较大的数交换到后面的一个位置上。重复这一操作,直到处理完本轮数列中最后两个元素,称为一轮排序。
当一轮排序完成时,最大的数就被轮换到本轮排序数列最右端位置上。重复上面的过程,经过 n - 1 轮后,就实现了数据升序排序。冒泡排序是一种稳定排序算法,即如果两个元素相等,是不会再交换的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换,所以相同元素的前后顺序并没有改变。
在这里插入图片描述

以下是各种语言的冒泡排序代码示例:

  • C 语言:
void bubble_sort(int* src,int length)//整数数组的排序
{
    int i =0,j = 0;
    int tmp = 0;
    /* 入参检查 */
    if(NULL == src || length <=0)
    {
        printf("(Error):Func:%s input...");
    }
    for (i = 0; i < length - 1; i++)
    {
        for (j = 0; j < length - i - 1; j++)
        {
            if(src[j]>src[j+1])
            {
                tmp = src[j];
                src[j] = src[j+1];
                src[j+1] = tmp;
            }
        }
    }
}
  • JavaScript:
//冒泡排序的排序过程是简单直观的,主要的执行步骤:
//1. 比较未排序序列中的相邻元素,如果两者的顺序不正确,则对两个元素进行交换;
//2. 重复地对剩余未排序的元素执行上一步,直至完成排序;
var bubbleSort = function (nums) {
    const n = nums.length;
    // 控制执行轮数
    for (let i = 0; i < n - 1; i++) {
        // 当次的所...
        for (let j = 0; j < n - i - 1; j++) {
            if (nums[j]> nums[j + 1]) {
                // 交换相邻元素的位置
                let temp = nums[j];
                nums[j]= nums[j + 1];
                nums[j + 1]= temp;
            }
        }
    }
    return nums;
}
  • Java:
public class BubbleSort{
    public static void bubbleSort(int[] array){
        int n = array.length;
        for(int i =0; i < n -1; i++){
            for(int j =0; j < n - i -1; j++){
                if(array[j]> array[j +1]){
                    // 交换相邻元素的位置
                    int temp = array[j];
                    array[j]= array[j +1];
                    array[j +1]= temp;
                }
            }
        }
    }
    public static void main(String[] args){
        int[] array ={64,34,25,12,22,11,90};
        bubbleSort(array);
        System.out.println("排序后的数组:");
        for(int i : array){
            System.out.print(i +" ");
        }
    }
}

综上所述,冒泡排序算法虽然简单,但在一些小规模数据的排序场景中仍然有其应用价值。

冒泡排序算法的基本思想

冒泡排序是一种简单的排序算法,其基本思想是重复地走访要排序的数列,一次比较两个相邻的元素,如果它们的顺序错误就把它们交换过来。具体来说,从数列的第一个元素开始,依次比较相邻的两个元素,若前面的元素比后面的元素大,则交换它们的位置。这样一轮比较下来,最大的元素就会“冒泡”到数列的末尾。接着,对剩余的未排序部分重复上述过程,直到整个数列都有序为止。

例如,对于数列[5, 3, 8, 2, 7],首先比较5和3,因为5大于3,所以交换它们的位置,数列变为[3, 5, 8, 2, 7]。接着比较5和8,不交换,再比较8和2,交换位置,数列变为[3, 5, 2, 8, 7]。最后比较8和7,交换位置,第一轮结束后数列变为[3, 5, 2, 7, 8]。然后对[3, 5, 2, 7]进行第二轮比较,以此类推,直到整个数列有序。

冒泡排序的优点是实现简单,容易理解,对于小规模数据的排序比较方便。但其缺点也很明显,时间复杂度较高,在最坏情况下,即待排序的元素已经按照逆序排列时,需要进行 n - 1 轮比较和交换操作,每轮需要进行 n - i 次比较和交换操作,其中 n 是待排序数组的元素数量,i 是当前轮数。因此,最坏情况下的时间复杂度为 O(n²)。

冒泡排序算法的稳定性

冒泡排序是一种稳定的排序算法。所谓稳定性,是指在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变。

在冒泡排序中,如果两个元素相等,是不会进行交换的;如果两个相等的元素没有相邻,那么即使通过前面的两两交换把两个相邻起来,这时候也不会交换。所以相同元素的前后顺序并没有改变,这就保证了冒泡排序的稳定性。

例如,对于数列[5, 3, 5’, 2, 7],其中5’表示另一个值为5的元素。在冒泡排序过程中,当比较到5和5’时,由于它们相等,不会进行交换。这样,在排序后的数列中,5和5’的相对位置与原数列保持一致。

冒泡排序算法的时间复杂度

冒泡排序的时间复杂度在最坏情况下为 O(n²),其中 n 为待排序的元素个数。在最坏情况下,即待排序的元素已经按照逆序排列,需要进行 n - 1 轮比较和交换操作,每轮需要进行 n - i 次比较和交换操作,因此总的时间复杂度为 O(n²)。

在最好情况下,即已经排好序的数组,时间复杂度为 O(n),因为只需要进行一轮比较就可以确定已经排好序。

平均情况下,时间复杂度也为 O(n²),因为平均需要进行 n/2 轮比较,每轮比较需要进行 n/2 次交换。

例如,对于一个包含 10 个元素的数组,在最坏情况下,第一轮需要比较 9 次,第二轮需要比较 8 次……以此类推,总共需要比较的次数为 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 = 45 次,接近 n²/2 的值。

冒泡排序算法的应用场景

冒泡排序适用于一些特定的场景:

  1. 数据规模较小:当数据规模较小时,冒泡排序的运行时间可能与其他更快的排序算法相差无几,或者甚至更快。例如,对包含几十个元素的数组进行排序。
  2. 数据已经接近有序:如果待排序的数据已经基本有序,冒泡排序的时间复杂度可以降低到 O(n)。比如,在一些数据处理过程中,已经经过了初步的整理,数据大部分已经有序,此时使用冒泡排序可以快速完成排序。
  3. 内存限制:冒泡排序是一种原地排序算法,它只需要在原始数组上进行交换操作,因此不需要额外的内存空间。这在内存受限的情况下可能会是一个优点。

但是,在大多数情况下,对于大规模数据集,更高效的排序算法如快速排序、归并排序等可能更适合使用。

C 语言冒泡排序代码示例

以下是用 C 语言实现冒泡排序的代码示例:

void bubble_sort(int arr[], int len) {
    int i, j, temp;
    for (i = 0; i < len - 1; i++) {
        for (j = 0; j < len - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
}

这段代码中,外层循环控制排序的轮数,内层循环对未排序的部分进行相邻元素的比较和交换。如果前面的元素大于后面的元素,就交换它们的位置,使较大的元素“冒泡”到后面。

JavaScript 冒泡排序代码示例

以下是用 JavaScript 实现的冒泡排序代码示例:

function bubbleSort(arr) {
    for (let i = 0; i < arr.length; i++) {
        for (let j = 0; j < arr.length - i - 1; j++) {
            if (arr[j] > arr[j + 1]) {
                let temp = arr[j];
                arr[j] = arr[j + 1];
                arr[j + 1] = temp;
            }
        }
    }
    return arr;
}

这段代码中,外层循环控制趟数,里层循环控制每一趟的循环次数。通过比较相邻的两个元素,如果顺序错误就进行交换,最终实现数组的排序。

Java 冒泡排序代码示例

以下是用 Java 实现的冒泡排序代码示例:

public class BubbleSort {
    public static void bubbleSort(int[] array) {
        int n = array.length;
        boolean swapped;
        for (int i = 0; i < n - 1; i++) {
            swapped = false;
            for (int j = 0; j < n - 1 - i; j++) {
                if (array[j] > array[j + 1]) {
                    int temp = array[j];
                    array[j] = array[j + 1];
                    array[j + 1] = temp;
                    swapped = true;
                }
            }
            if (!swapped) {
                break;
            }
        }
    }
}

这段代码中,外层循环控制趟数,通过设置一个标志位 swapped,如果在一趟排序中没有发生交换,说明数组已经有序,可以提前退出循环,提高效率。

总结

冒泡排序算法虽然简单易懂,但时间复杂度较高,适用于数据规模较小、数据接近有序或内存受限的场景。在实际应用中,应根据具体情况选择合适的排序算法。

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

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

相关文章

农产品商城系统小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;产品分类管理&#xff0c;热销农产品管理&#xff0c;订单管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;热销弄产品&#xff0c;网站公告&#…

基于c++实现的简易shell

代码逻辑 核心思想 解析命令行&#xff0c;拆解命令及其选项创建子进程&#xff0c;在子进程中执行命令如果是前台执行命令&#xff0c;则父进程就阻塞等待子进程中命令执行结束后回收子进程的资源如果是后台执行命令&#xff0c;则父进程不进行阻塞等待&#xff0c;可继续向下…

STM32 软件触发ADC采集

0.91寸OLED屏幕大小的音频频谱&#xff0c;炫酷&#xff01; STM32另一个很少人知道的的功能——时钟监测 晶振与软件的关系&#xff08;深度理解&#xff09; STM32单片机一种另类的IO初始化方法 ADC是一个十分重要的功能&#xff0c;几乎任何一款单片机都会包含这个功能&a…

记一次MySQL索引不当引发死锁问题

一、前言 在并发量很低的情况下&#xff0c;mysql 的响应时延一切正常&#xff0c;一旦并发量上去了&#xff0c;mysql就会出现死锁的情况&#xff0c;你有没有遇到过&#xff1f;到底是是什么原因导致的呢&#xff0c;让我们一起看看真实的案例。 二、遇到的问题 先介绍一下…

LabVIEW提高开发效率技巧----利用第三方库和工具

LabVIEW开发不仅依赖于自身强大的图形化编程能力&#xff0c;还得益于其庞大的用户社区和丰富的第三方库。这些工具和库能够帮助开发者快速解决问题&#xff0c;提升开发效率&#xff0c;避免从头开始编写代码。 1. LabVIEW工具网络&#xff08;NI Tools Network&#xff09; …

MateBook 16s 2023在Deepin下开启性能模式,调节风扇转速到最大,全网首发!

方法 在Deepin下按住Fnp快捷键&#xff0c;开启性能模式。 验证 首先去debian下载acpi-call-dkms https://packages.debian.org/sid/all/acpi-call-dkms/download 然后使用root用户执行&#xff1a; apt install --simulate ./acpi-call-dkms_1.2.2-2.1_all.deb apt inst…

LeetCode 面试经典150题 191.位1的个数

Java中的算术右移和逻辑右移的区别 题目&#xff1a;编写一个函数&#xff0c;获取一个正整数的二进制形式并返回其二进制表达式中设置位的个数&#xff08;也被称为汉明重量&#xff09;。 设置位的个数即二进制中1的个数。 思路&#xff1a;方法一&#xff1a;因为正数的原…

基于阿里云免费部署Qwen1-8B-chat模型并进行lora参数微调从0到1上手操作

文章目录 一、申请资源二、创建实例三、克隆微调数据四、部署Qwen1-8B-chat模型1、环境配置2、模型下载3、本地模型部署 五、模型微调1、拉取Qwen仓库源码2、微调配置3、合并微调参数4、本地部署微调模型 一、申请资源 阿里云账号申请PAI资源详细教程我已于部署ChatGLM3时写过…

Golang | Leetcode Golang题解之第430题扁平化多级双向链表

题目&#xff1a; 题解&#xff1a; func dfs(node *Node) (last *Node) {cur : nodefor cur ! nil {next : cur.Next// 如果有子节点&#xff0c;那么首先处理子节点if cur.Child ! nil {childLast : dfs(cur.Child)next cur.Next// 将 node 与 child 相连cur.Next cur.Chi…

遗传算法与深度学习实战(14)——进化策略详解与实现

遗传算法与深度学习实战&#xff08;14&#xff09;——进化策略详解与实现 0. 前言1. 进化策略1.1 进化策略原理1.2 将进化策略应用于函数逼近 2. 实现进化策略小结系列链接 0. 前言 进化策略 (Evolutionary Strategies, ES) 是进化计算和遗传方法的扩展&#xff0c;增加了控…

【Python学习手册(第四版)】学习笔记24-高级模块话题

个人总结难免疏漏&#xff0c;请多包涵。更多内容请查看原文。本文以及学习笔记系列仅用于个人学习、研究交流。 本来计划中秋发布几篇文章&#xff0c;结果阳了&#xff0c;发烧、头疼、咽疼&#xff0c;修养了近一周&#xff0c;还没好完。希望大家都能有个好身体&#xff0…

proteus仿真软件简体中文版网盘资源下载(附教程)

对于电子通信专业的小伙伴来说&#xff0c;今天文章的标题应该不会陌生。Proteus是一款具有广泛应用的仿真软件&#xff0c;它的功能非常强大&#xff0c;适用于所有单片机的仿真工作&#xff0c;能够从原理图、调试、到与电路的协同仿真一条龙全部搞定&#xff0c;受到所有用户…

自己开发了一个电脑上滚动背单词的软件

在这个快节奏的时代&#xff0c;我们每天都在忙碌中度过&#xff0c;手机虽然方便&#xff0c;但往往难以找到一整块时间来专心背单词。然而&#xff0c;你是否意识到&#xff0c;每天坐在电脑前的时间远比使用手机的时间要长&#xff1f;现在我们来介绍一个新型的学习软件灵思…

Fyne ( go跨平台GUI )中文文档-容器和布局 (四)

本文档注意参考官网(developer.fyne.io/) 编写, 只保留基本用法 go代码展示为Go 1.16 及更高版本, ide为goland2021.2 这是一个系列文章&#xff1a; Fyne ( go跨平台GUI )中文文档-入门(一)-CSDN博客 Fyne ( go跨平台GUI )中文文档-Fyne总览(二)-CSDN博客 Fyne ( go跨平台GUI…

XSS—xss-labs靶场通关

level 1 JS弹窗函数alert() <script>alert()</script> level 2 闭合绕过 "> <script>alert()</script> <" level 3 onfocus事件在元素获得焦点时触发&#xff0c;最常与 <input>、<select> 和 <a> 标签一起使用…

科研绘图系列:R语言多个AUC曲线图(multiple AUC curves)

文章目录 介绍加载R包导入数据数据预处理画图输出结果组图系统信息介绍 多个ROC曲线在同一张图上可以直观地展示和比较不同模型或方法的性能。这种图通常被称为ROC曲线图,它通过比较不同模型的ROC曲线下的面积(AUC)大小来比较模型的优劣。AUC值越大,模型的诊断或预测效果越…

生成自签名证书和私钥

可以使用 OpenSSL 来生成自签名证书&#xff08;linux上执行&#xff09;&#xff1a; openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 365 -nodes生成 key.pem&#xff08;私钥&#xff09;和 cert.pem&#xff08;证书&#xff09; 当执行这个 …

某集群管理系统存在任意文件读取漏洞

你为什么要拼命努力&#xff1f;父母的白发&#xff0c;想去的地方很远&#xff0c;想要的东西很贵&#xff0c;喜欢的人很优秀&#xff0c;周围人的嘲笑&#xff0c;以及&#xff0c;天生傲骨。 漏洞描述 利用漏洞&#xff0c;攻击者可以读取 Windows 或 Linux 服务器上的任…

ER论文阅读-Decoupled Multimodal Distilling for Emotion Recognition

基本介绍&#xff1a;CVPR, 2023, CCF-A 原文链接&#xff1a;https://openaccess.thecvf.com/content/CVPR2023/papers/Li_Decoupled_Multimodal_Distilling_for_Emotion_Recognition_CVPR_2023_paper.pdf Abstract 多模态情感识别&#xff08;MER&#xff09;旨在通过语言、…

基于STM32残疾人辅助行走系统

要么是家人陪伴&#xff0c;要么是类似导盲犬的动物辅助&#xff0c;家人还有事要做&#xff0c;不一定实时在场&#xff0c;而动物辅助也可能会出现新的问题&#xff0c;威胁残疾人身体安全。因此利用现代计算机技术、传感器检测设备和物联网技术设计这一款辅助残疾人行走的智…