【数据结构与算法】排序算法:冒泡排序,冒泡排序优化,选择排序、选择排序优化

目录

一、冒泡排序

1、冒泡排序思想

2、冒泡排序算法的性能分析

代码实现:

二、选择排序

1、选择排序思想

2、选择排序算法的性能分析 

代码实现:


一、冒泡排序

1、冒泡排序思想

冒泡排序的基本思想是通过相邻元素之间的比较和交换来逐步将最大(或最小)的元素移到右边(或左边)。具体来说,冒泡排序的步骤如下:

  1. 从数组的第一个元素开始,依次比较相邻的两个元素。如果前面的元素大于后面的元素,则交换它们的位置,以使较大的元素向右移动。
  2. 继续向数组的下一个相邻元素进行比较和交换,直到最后一个元素,此时最大的元素已经移到了数组的最右侧。
  3. 重复以上步骤,但这次只需要比较和交换前 n-1 个元素,因为最大的元素已经在正确的位置上。
  4. 重复进行 n-1 轮比较和交换,直到所有元素都按照从小到大(或从大到小)的顺序排列。

2、冒泡排序算法的性能分析

  • 最好的情况下,当输入数组已经是有序的,冒泡排序只需进行一轮比较,时间复杂度为 O(n)。
  • 最坏的情况下,当输入数组是逆序的,冒泡排序需要进行 n-1 轮比较和交换,时间复杂度为 O(n^2)。
  • 平均情况下,冒泡排序的时间复杂度为 O(n^2)。
  • 冒泡排序是一种稳定排序算法,不会改变相等元素的相对顺序。
  • 冒泡排序是一种原地排序算法,不需要额外的空间。

代码实现:

1、普通版本:

// 定义一个交换函数,用于交换两个整数的值
void swap(int* a, int* b)
{
    int temp;
    temp = *a;
    *a = *b;
    *b = temp;
}

// 冒泡排序函数,对数组进行排序
void BubbleSort(int* a, int n)
{
    int i, j;
    
    // 外层循环控制排序的轮数
    for (i = 0; i < n - 1; i++)
    {
        // 内层循环进行相邻元素的比较和交换
        for (j = 0; j < n - i - 1; j++)
        {
            // 如果前一个元素大于后一个元素,则交换它们的位置
            if (a[j] > a[j + 1])
            {
                swap(&a[j], &a[j + 1]);
            }
        }
    }
}

2、优化版本 :

思想:在优化版本的冒泡排序算法中,通过添加一个标记变量flag,可以在一轮排序过程中标记是否有进行过交换操作,如果某一轮排序中没有进行过任何交换,说明数组已经有序,可以提前结束排序。

// 定义一个交换函数,用于交换两个整数的值
void swap(int* a, int* b)
{
    int temp;
    temp = *a;
    *a = *b;
    *b = temp;
}

// 冒泡排序函数,对数组进行排序
void BubbleSortPro(int* a, int n)
{
    int i, j, flag = 0; 
    // flag用于标记是否有交换发生,初始值为0
    
    // 外层循环控制排序的轮数
    for (i = 0; i < n - 1; i++)
    {
        flag = 0; // 在每一轮开始时,将flag重置为0
        
        // 内层循环进行相邻元素的比较和交换
        for (j = 0; j < n - i - 1; j++)
        {
            // 如果前一个元素大于后一个元素,则交换它们的位置,并将flag设置为1
            if (a[j] > a[j + 1])
            {
                swap(&a[j], &a[j + 1]);
                flag = 1;
            }
        }
        
        // 如果在一轮排序中没有进行过任何交换,说明数组已经有序,可以提前结束排序
        if (flag == 0)
        {
            break;
        }
    }
}

二、选择排序

1、选择排序思想

选择排序的基本思想可以概括为以下几个步骤:

  1. 遍历待排序的数组,将数组中的第一个元素视为当前最小值。
  2. 在剩余的未排序部分中,依次查找比当前最小值更小的元素。
  3. 如果找到了比当前最小值更小的元素,则将其标记为新的最小值。
  4. 遍历完未排序部分,将新的最小值与当前最小值交换位置。
  5. 如此循环,直到所有元素都被排序。

通过每次从剩余未排序部分选择最小的元素,并将其放在已排序部分的末尾,逐步构建有序序列。

2、选择排序算法的性能分析 

  • 选择排序的时间复杂度为O(n^2),其中n是待排序数组的元素个数。这是因为在每一轮遍历中,需要比较剩余未排序部分的所有元素,最坏情况下要进行n-1次比较。总共需要进行n-1轮遍历,因此时间复杂度为O(n^2)。
  • 选择排序是一种不稳定的排序算法。当待排序数组中存在相同元素时,选择排序可能会改变相同元素的相对顺序。具体来说,在选择过程中,如果当前的最小元素与其他相同元素交换位置,可能会改变它们的相对顺序。
  • 选择排序是一种原地排序算法,即排序过程中不需要额外的空间。它只需要一个额外的变量来记录最小(或最大)元素的位置,通过交换元素位置来实现排序,所以空间复杂度为O(1)。

综上所述,选择排序的时间复杂度为O(n^2),空间复杂度为O(1),并且是一种不稳定的排序算法。

 

代码实现:

1、普通版本:

void swap(int* a,int* b)
{
    int temp;
    temp=*a;
    *a=*b;
    *b=temp;
}

void SelctSort(int* a, int n)
{
    int i, j, key;

    // 遍历数组,i表示已排序部分的末尾元素的索引
    for (i = 0; i < n - 1; i++)
    {
        key = i; // 将当前位置视为最小值的索引

        // 在未排序部分中查找最小值
        for (j = i + 1; j < n; j++)
        {
            if (a[key] > a[j])
            {
                key = j; // 更新最小值的索引
            }
        }

        // 如果最小值不是当前位置的元素,则交换位置
        if (key != i)
        {
            swap(&a[i], &a[key]);
        }
    }
}

 2、优化版本

 优化版本的思想是在选择排序的基础上,同时追踪并找出未排序部分的最大值和最小值,并将它们分别放置在已排序部分的末尾和开头。通过这种方式,可以减少交换的次数,从而提高排序的效率。

void swap(int* a,int* b)
{
    int temp;
    temp=*a;
    *a=*b;
    *b=temp;
}

void SelctSortPro(int* a, int n)
{
    int i, j;
    int begin = 0, end = n - 1;
    int maxi = end, mini = begin;

    // 在每一次循环中,将未排序部分的最大值和最小值分别放置在已排序部分的末尾和开头
    while (begin < end)
    {
        i = begin;
        j = end;
        maxi = end;
        mini = begin;

        // 在未排序部分中查找最大值和最小值
        while (i <= end)
        {
            if (a[maxi] < a[i])
            {
                maxi = i; // 更新最大值的索引
            }
            if (a[mini] > a[i])
            {
                mini = i; // 更新最小值的索引
            }
            i++;
        }

        // 将最小值放置在已排序部分的开头
        swap(&a[begin], &a[mini]);
        
        // 如果最大值所在位置等于begin,更新最大值所在位置为mini
        if (maxi == begin)
        {
            maxi = mini;
        }
        
        // 将最大值放置在已排序部分的末尾
        swap(&a[end], &a[maxi]);

        // 更新已排序部分和未排序部分的起始和结束位置
        begin++;
        end--;
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

轮胎侧偏刚度线性插值方法

一、trucksim取数据 步骤一 步骤二 二、数据导入到matlab中 利用simulink的look up table模块 1是侧偏角&#xff1b;2是垂直载荷&#xff1b;输出是侧向力。 侧向力除以侧偏角就是实时的侧偏刚度。

unocss+iconify技术在vue项目中使用20000+的图标

安装依赖 npm i unocss iconify/json配置依赖 vue.config.js文件 uno.config.js文件 main.js文件 使用 <i class"i-fa:user"></i> <i class"i-fa:key"></i>class名是 i- 开头&#xff0c;跟库名:图标名&#xff0c;那都有什么库…

数据结构之dict类

dict类 dict 是字典类。什么是字典&#xff08;Dictionary&#xff09;呢&#xff1f;就是一个可以通过索引找到对象的数据类型。在Python 的dict类里&#xff0c;索引就是“键”&#xff0c;对象也叫“值”&#xff0c;二者合起来就叫“键值对”。每个“键值对”之间用逗号&a…

“深入理解 Docker 和 Nacos 的单个部署与集成部署“

目录 引言&#xff1a;Docker Nacos 单个部署1.1 什么是 Docker&#xff1f;Docker 的概念和工作原理Docker 为什么受到广泛应用和认可 1.2 什么是 Nacos&#xff1f;Nacos 的核心功能和特点Nacos 在微服务架构中的作用 1.3 Docker 单个部署 Nacos Docker Nacos 集成部署总结&a…

【从零开始学习Redis | 第七篇】利用Redis构造全局唯一ID(含其他构造方法)

目录 前言&#xff1a; 什么是全局唯一ID&#xff1f; 尝试构造全局唯一ID&#xff1a; 其他构造全局唯一ID的方法 1.基于数据库自增构造全局唯一ID&#xff1a; 2.基于UUID构造全局唯一ID&#xff1a; 3.基于雪花算法构造全局唯一ID&#xff1a; 总结&#xff1a; 前…

leetcode 013二维区域和检索---矩阵不可变

给定一个二维矩阵 matrix&#xff0c;以下类型的多个请求&#xff1a; 计算其子矩形范围内元素的总和&#xff0c;该子矩阵的左上角为 (row1, col1) &#xff0c;右下角为 (row2, col2) 。 实现 NumMatrix 类&#xff1a; NumMatrix(int[][] matrix) 给定整数矩阵 matrix 进…

Python数据分析案例36——基于神经网络的AQI多步预测(空气质量预测)

案例背景 不知道大家发现了没&#xff0c;现在的神经网络做时间序列的预测都是单步预测&#xff0c;即(需要使用X的t-n期到X的t-1期的数据去预测X的t期的数据)&#xff0c;这种预测只能预测一个点&#xff0c;我需要预测X的t1期的数据就没办法了&#xff0c;有的同学说可以把预…

部署Sqli-labs靶场:一篇文章解析全过程

部署Sqli-labs靶场&#xff1a;一篇文章解析全过程 0x01 前言 Sqli-labs是一个在线的SQL注入练习平台&#xff0c;提供了一系列关卡供用户练习SQL注入的技巧和防范方法。在这个平台上&#xff0c;用户可以尝试注入攻击&#xff0c;并测试自己的技能和工具&#xff0c;同时也可…

无心剑七绝《腊八粥香》

七绝腊八粥香 欣逢腊八粥浓香 五谷丰登聚宝庄 祈福心诚情不尽 佳肴共品待春芳 2024年1月18日 平水韵七阳平韵 这首七言绝句《腊八粥香》以腊八节为背景&#xff0c;描绘了人们欢庆腊八、祈福迎新的情景。 首句“欣逢腊八粥浓香”&#xff0c;开门见山地点明了主题——腊八节&a…

【笔记】《WebGL 编程指南》第 2 章 WebGL 入门

第一个 WebGL 程序 【P42】 默认情况下&#xff0c;<canvas>是透明的 【P44】 它不直接提供绘图方法&#xff0c;而是提供一种叫上下文&#xff08;context&#xff09;的机制来进行绘图。 【P45】 计算机系统通常使用红、绿、蓝这三原色组合来表示颜色&#xff0c;这种…

IMX6LL|时钟控制

一.时钟控制模块 4个层次配置芯片时钟 晶振时钟PLL与PFD时钟PLL选择时钟根时钟/外设时钟 1.1晶振时钟 系统时钟来源 RTC时钟源&#xff1a;32.768KHz&#xff0c;连接RTC模块&#xff0c;进行时间计算。系统时钟&#xff1a;24MHz&#xff0c;芯片主晶振 1.2PLL和PFD倍频时钟…

十一、常用API——正则表达式

目录 练习1&#xff1a; 正则表达式的作用 正则表达式 字符类&#xff08;只匹配一个字符&#xff09; 预定义字符&#xff08;只匹配一个字符&#xff09; 数量词 类 Pattern 正则表达式的构造摘要 反斜线、转义和引用 字符类 行结束符 组和捕获 Unicode 支持 与…

leetcode234. 回文链表

题目 给你一个单链表的头节点 head &#xff0c;请你判断该链表是否为回文链表。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&#xff1a; 输入&#xff1a;head [1,2,2,1] 输出&#xff1a;true示例 2&#xff1a; 输入&#xff1a;hea…

关于KT6368A双模蓝牙芯片的BLE在ios的lightblue大数量数据测试

测试简介 关于KT6368A双模蓝牙芯片的BLE在ios的lightblue app大数量数据测试 测试环境&#xff1a;iphone7 。KT6368A双模程序96B6 App&#xff1a;lightblue ios端 可以打开log日志查看通讯流程 测试数据&#xff1a;长度是1224个字节&#xff0c;单次直接发给KT6368A&a…

ELK之Filebeat输出日志格式设置及输出字段过滤和修改

一、Filebeat输出日志格式设置 1.1 编辑vim filebeat.yml文件,修改输出格式设置 # output to console output.console:codec.format: string: %{[@timestamp]} %{[message]}pretty: true### 1.2 测试 执行 ./filebeat -e 可以看到/tmp/access.log(目前文件里只有140.77.188…

【Java 设计模式】结构型之桥接模式

文章目录 1. 定义2. 应用场景3. 代码实现结语 桥接模式&#xff08;Bridge Pattern&#xff09;是一种结构型设计模式&#xff0c;它将抽象部分与实现部分分离&#xff0c;使它们可以独立变化&#xff0c;从而降低它们之间的耦合。桥接模式通过将抽象部分和实现部分分离&#x…

【PyTorch】PyTorch之Tensors操作篇

文章目录 前言一、Tensor创建1、TENSOR2、SPARSE_COO_TENSOR3、SPARSE_CSR_TENSOR4、ASARRAY5、AS_TENSOR6、FROM_NUMPY7、FROMBUFFER8、ZEROS和ZEROS_LIKE9、ONES和ONES_LIKE10、ARANGE11、LINSPACE12、LOGSPACE13、EYE14、EMPTY和EMPTY_LIKE15、FULL和FULL_LIKE 前言 介绍Te…

Docker搭建MySQL主从数据库-亲测有效

1、测试环境概述 1、使用MySQL5.7.35版本 2、使用Centos7操作系统 3、使用Docker20版本 案例中描述了整个测试的详细过程 2、安装Docker 2.1、如果已经安装docker,可以先卸载 yum remove -y docker \ docker-client \ docker-client-latest \ docker-common \ docker-l…

Nginx重写功能location与rewrite

1. location 从功能看 rewrite 和 location 似乎有点像&#xff0c;都能实现跳转&#xff0c;主要区别在于 rewrite 是在同一域名内更改获取资源的路径&#xff0c;而 location 是对一类路径做控制访问或反向代理&#xff0c;还可以proxy_pass 到其他机器。 rewrite 对访问的…

java数据结构与算法刷题-----LeetCode977. 有序数组的平方

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 文章目录 1. 时间复杂度 空间复杂度 O(n * l o g 2 n log_2{n} log2​…