0089 时间复杂度,冒泡排序

news2025/2/24 3:03:28

 

 

 

 

 

 

 

 

 

/*
 * 排序也称排序算法(Sort Algorithm)
 * 排序是将一组数据,依指定的顺序进行排列的过程。
 * 
 * 排序分类
 * 1.内部排序:将需要处理的所有数据都加载到内存存储器中进行排序(使用内存)
 *         插入排序
 *             1.直接插入排序
 *             2.希尔排序
 *         选择排序
 *             3.简单选择排序
 *             4.堆排序
 *         交换排序
 *             5.冒泡排序
 *             6.快速排序
 *         7.归并排序
 * 
 *         8.基数排序
 * 
 * 2.外部排序:数据量过大,无法全部加载到内存,借助外部存储进行排序(使用内存和外存结合)
 * 
 * 
 * 算法的时间复杂度
 * 
 *     度量一个程序(算法)执行时间的两种方法
 *     1.事后统计
 *         方法可行,但需要实际运行该程序,且所得时间的统计量依赖于计算机硬件
 *     2.事前统计
 *         通过分析某个算法得时间复杂度来判断哪个算法更优
 * 
 *     时间频度
 *     一个算法花费的时间与算法中语句的执行次数成正比,哪个算法中语句执行次数多,它花费的时间就多。
 *     一个算法中的语句执行次数称为语句频度或时间频度,记为T(n)
 *     可以忽略常数项、低次项和系数
 * 
 *     如计算1-100所有数字之和,设计两种算法:(for循环和直接计算)
 * 
 *    for循环
 *     int total = 0;
 *     int end = 100;
 *  for(int i = 1;i <= end;i++){
 *      total += i;    
 *  }
 *  T(n)=n+1
 *  
 *  直接计算
 *  total = (1+end)*end/2
 *  T(n)=1
 *  
 *  时间复杂度
 *  1.一般情况下,算法中的基本操作语句的重复执行次数是问题规模n的某个函数,用T(n)表示,
 *    若有某个辅助函数f(n),使得当n趋于无穷大时,T(n)/f(n)的极限值为不等于零的常数
 *    则称f(n)是T(n)的同数量级函数。记为T(n)=O(f(n))
 *    称O(f(n))为算法的渐进时间复杂度,简称为时间复杂度
 *    
 *  2.T(n)不同,但时间复杂度可能相同。如T(n)=n²+7n+6与T(n)=3n²+2n+2 
 *    它们的T(n)不同,但时间复杂度相同,都为O(n²)
 *  
 *  3.计算时间复杂度的方法
 *      1.用常数1代替运行时间中的所有加法常数
 *      2.修改后的运行次数函数中,只保留最高阶项
 *      3.去除最高阶项的系数
 *  
 *  常见时间复杂度
 *  1.常数阶O(1)
 *  2.对数阶O(log₂n)
 *  3.线性阶O(n)
 *  4.线性对数阶O(nlog₂n)
 *  5.平方阶O(n²)
 *  6.立方阶O(n³)
 *  7.k次方阶O(n^k)
 *  8.指数阶O(2ⁿ)
 *  
 *  时间复杂度从大到小依次为:O(1)<O(log₂n)<O(n)<O(nlog₂n)<O(n²)<O(n³)<O(n^k)<O(2ⁿ)<O(n!)
 *  随着问题规模n的不断增大,上述时间复杂度不断增大,算法的执行效率越低
 *  所以应尽可能避免使用指数阶的算法
 *  
 *  1.常数阶O(1)
 *      int i = 1;
 *      int j = 2;
 *         i++;
 *      j++;
 *      int m = i + j;
 *  无论代码执行了多少行,只要没有循环等复杂结构,代码执行时并不随着某个变量的增长而增长,时间复杂度就是O(1)
 *  
 *  2.对数阶O(log₂n)
 *      int i = 1;
 *      while(i < n){
 *          i = i * 2;
 *      }
 *  在while循环里,每次都将i乘以2,i距离n越来越远了,假设循环x次后,i就大于2,此时循环退出。
 *  即2的x次方=n,x=log₂n,即当循环log₂n次后,代码结束,所以时间复杂度为O(log₂n)
 *  若i=i*3,则是O(log₃n)
 *  
 *  3.线性阶O(n)
 *  for(i = 1;i <= n;++i){
 *      j = i;
 *      j++;
 *  }
 *  for循环里的代码会执行n次,因此消耗时间是随着n的变化而变化,时间复杂度为O(n)
 *  
 *  4.线性对数阶O(nlog₂n)
 *  for(m = 1;m < n;m++){
 *      i = 1;
 *      while(i < n){
 *            i = i * 2;      
 *      }
 *  }
 *  将时间复杂度为O(log₂n)的代码循环n遍,那么时间复杂度就为n * O(log₂n) 即O(nlog₂n)
 *  
 *  5.平方阶O(n²)
 *  for(x = 1;i <= n;x++){
 *      for(i = 1;i <= n;i++){
 *          j = i;
 *          j++;
 *      }
 *  }
 *  把O(n)的代码在嵌套循环一遍,时间复杂度就为O(n*n),即O(n²),如果把n改为m,则时间复杂度为O(m*n)
 *     立方阶和k次方阶相当于3层n循环,k层n循环...
 * 
 *     平均时间复杂度和最坏时间复杂度
 *     1.平均时间复杂度是指所有可能的输入实例均以等概率出现的概率下,该算法的运行时间
 *     2.一般讨论的时间复杂度是最坏时间复杂度。
 *       原因是:最坏时间复杂度是算法在任何输入实力上运行时间的界限,保证了算法的运行时间不会比最坏情况更长
 *     3.平均时间复杂度和最坏时间复杂度是否一致,和算法有关
 * 
 *     空间复杂度
 *     1.类似于时间复杂度的讨论,一个算法的空间复杂度(Space Complexity)定义为
 *       该算法所耗费的存储空间,也是问题规模n的函数
 *     2.空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度
 *       有的算法需要占用的临时工作单元数与解决问题规模n有关,随着n的增大而增大,当n较大时,将占用较多的存储单元
 *     3.在做算法分析时,主要讨论时间复杂度,从用户使用体验上看,更看重的是程序执行的速度。
 *       一些缓存产品和算法本质就是用空间换时间。
 *  
 */

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;

/*
 * 冒泡排序
 *     通过待排序序列从前向后(从下标较小的元素开始),依次比较相邻元素的值
 *     若发现逆序则交换,使值较大的元素逐渐从前移到后,就像水里的气泡一样向上冒
 * 
 * 因为排序的过程中,各元素不断接近自己的位置,如果一趟比较下来没有进行交换,就说明序列有序
 * 因此要在排序过程中设置一个flag判断元素是否进行过交换,从而减少不必要的比较
 * 
 * 冒泡排序过程
 * 原始:3,9,-1,10,-2
 * 第一次排序
 * (3与9比较)
 * 3,9,-1,10,-2
 * (9与-1比较)
 * 3,-1,9,10,-2
 * (9与10比较)
 * 3,-1,9,10,-2
 * (10与-2比较)
 * 3,-1,9,-2,10    //确定了10
 * 
 * 第二次排序
 * (3与-1比较)
 * -1,3,9,-2,10
 * (3与9比较)
 * -1,3,9,-2,10
 * (9与-2比较)
 * -1,3,-2,9,20    //确定了9
 * 
 * 第三次排序
 * (-1和3比较)
 * -1,3,-2,9,10
 * (3和-2比较)
 * -1,-2,3,9,10     //确定了3
 * 
 * 第四次排序
 * (-1和-2比较)
 * -2,-1,3,9,10    //确定了-1
 * 
 * 总结
 * 1.一共进行数组大小-1次循环
 * 2.每一次排序的次数在逐渐减少
 * 3.优化:如果发现在某次排序中没有发生交换,可提前结束冒泡排序
 */
public class BubbleSorting_ {
    public static void main(String[] args) {
        int[] arr = {3,9,-1,10,-2};
        System.out.println("排序前");
        System.out.println(Arrays.toString(arr));
        bubbleSort(arr);
        System.out.println("排序后");
        System.out.println(Arrays.toString(arr));
      
        //测试冒泡排序的速度
        int[] arr2 = new int[80000];
        for(int i = 0;i < 80000;i++) {
            arr2[i] = (int)(Math.random() * 80000);
        }
        Date date1 = new Date();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyy-MM-dd HH:mm:ss");
        String date1Str = simpleDateFormat.format(date1);
        System.out.println("排序前的时间=" + date1Str);
        
        bubbleSort(arr2);
        
        Date date2 = new Date();
        String date2Str = simpleDateFormat.format(date2);
        System.out.println("排序后的时间=" + date2Str);
    }
/*
        //第一次排序
        int temp = 0;//临时变量
        for(int j = 0;j < arr.length - 1 - 0;j++) {
            //如果前面数大就交换
            if (arr[j] > arr[j+1]) {
                temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
        System.out.println("第一次排序");
        System.out.println(Arrays.toString(arr));
        
        //第二次排序
        for(int j = 0;j < arr.length - 1 - 1;j++) {
            //如果前面数大就交换
            if (arr[j] > arr[j+1]) {
                temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
        System.out.println("第二次排序");
        System.out.println(Arrays.toString(arr));
        
        //第三次排序
        for(int j = 0;j < arr.length - 1 - 2;j++) {
            //如果前面数大就交换
            if (arr[j] > arr[j+1]) {
                temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
        System.out.println("第三次排序");
        System.out.println(Arrays.toString(arr));
        
        //第四次排序
        for(int j = 0;j < arr.length - 1 - 3;j++) {
            //如果前面数大就交换
            if (arr[j] > arr[j+1]) {
                temp = arr[j];
                arr[j] = arr[j+1];
                arr[j+1] = temp;
            }
        }
        System.out.println("第四次排序");
        System.out.println(Arrays.toString(arr));
*/    
/*
        int temp = 0;//临时变量
        for(int i = 0;i < arr.length - 1;i++) {
            for(int j = 0;j < arr.length - 1 - i;j++) {
                if (arr[j] > arr[j+1]) {
                    temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
            System.out.println("第" + (i+1) + "次排序");
            System.out.println(Arrays.toString(arr));
        }
*/        
        //优化:设置标识变量,并封装成方法
    public static void bubbleSort(int[] arr) {
        int temp = 0;//临时变量
        boolean flag = false;//标识变量,标识是否进行过交换
        for(int i = 0;i < arr.length - 1;i++) {
            for(int j = 0;j < arr.length - 1 - i;j++) {
                if (arr[j] > arr[j+1]) {
                    flag = true;
                    temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
            //System.out.println("第" + (i+1) + "次排序");
            //System.out.println(Arrays.toString(arr));
            
            if (flag == false) {//说明没有发生交换
                break;
            }else {
                flag = false;//重置flag,进行下次判断
            }
        }
    }
}

 

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

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

相关文章

彻底搞懂WeakMap和Map

一 、Map Map是一种叫做字典的数据结构&#xff0c;Map 对象保存不重复键值对&#xff0c;并且能够记住键的原始插入顺序 Map的属性和方法* 属性&#xff1a; size&#xff1a; 返回所包含的键值对长度* 操作方法&#xff1a;* set(key,val): 添加新键值对* get(key): 通过传…

Linux--信号signal、父子进程、SIGCHLD信号相关命令

目录 1.概念&#xff1a; 2.信号的存储位置&#xff1a; 3.常见的信号的值以及对应的功能说明&#xff1a; 4.信号的值在系统源码中的定义&#xff1a; 5.响应方式&#xff1a; 6.改变信号的相应方式&#xff1a; (1)设置信号的响应方式: (2)默认:SIG_DFL;忽略:SIG_IGN…

Android Studio 新版本 Logcat 的使用

前言 最近&#xff0c;Android Studio 自动更新了自带的 Logcat 工具&#xff0c;整体外观和使用方法变得和之前完全不同了。一开始我以为是自己按到什么不该按的按钮&#xff0c;把 Logcat 弄坏了&#xff0c;后来才知道是版本更新导致的。新版本的 Logcat 用命令来过滤信息&…

jmeter变量函数以及抓包用法

抓包 代理服务器&#xff1a; 自己启动一个代理服务器 本地&#xff0c;要使用代理服务器的ip和端口&#xff0c;使用自己启动的代理服务器 操作步骤 添加线程组测试计划 > 非测试元件 > http代理服务器一定要修改 修改为** 测试计划>线程 ip就是你自己电脑的ip&…

Activity

Activity生命周期图 官网的 Activity 的生命周期图&#xff1a; 在官方文档中给出了说明&#xff0c;不允许在 onPause() 方法中执行耗时操作&#xff0c;因为这会影响到新 Activity 的启动。 常见情况下Activity生命周期的回调 &#xff08;A 与 B 表示不同的 Activity &a…

(硬件设计)老工程师的经验之道

系列文章目录 1.元件基础 2.电路设计 3.PCB设计 4.元件焊接 5.板子调试 6.程序设计 7.算法学习 8.编写exe 9.检测标准 10.项目举例 11.职业规划 文章目录前言1、用蜡烛油固定电位器2、电路板接插件用彩色接插件前言 送给大学毕业后找不到奋斗方向的你&#xff08;每周不定时…

Python----科学计数法、同时给多个变量赋值、eval函数、math库函数、复数(complex())、内置的数值运算函数、内置的数值运算操作符

科学计数法使用字母"e"或者“E”作为幂的符号&#xff0c;以10为基数&#xff0c;科学计数法的含义如下&#xff1a; 96e4&#xff1a;96乘10的4次幂 4.3e-3&#xff1a;4.3乘10的负三次幂 aeb&#xff1a;a*10*b 同时给多个变量赋值格式: 变量1&#xff0c;变量2表…

基于Python的电影推荐系统

电影推荐系统 目录 电影推荐系统 1 数据描述 1变量说明 1程序介绍 2 本次课程作业在 small-movielens 数据集的基础上&#xff0c;对用户、电影、评分数据进行了处理&#xff0c;然后根据 Pearson 相关系数计算出用户与其他用户之间的相似度&#xff0c;根据相似度进行推荐和…

用Python来表白,把情书写进她的照片里

前言 这不已经十一月了&#xff0c;22年马上就过完了&#xff0c;各位兄弟有对象了吗&#xff0c;现在就是缺钱还缺对象 退一步来说&#xff0c;有心仪的人吗啊&#xff0c;如果有的话&#xff0c;看看这篇 程序员的表白小妙招吧 实现步骤 想要实现把情书写在像素中&#xf…

【Web-HTML基础】颜色赋值、背景图片、文本和字体相关样式、元素的显示方式display、盒子模型、部分标签自带外边距或内边距

目录 颜色赋值 背景图片 文本和字体相关样式 元素的显示方式display 盒子模型 盒子模型之content内容 盒子模型之margin外边距 盒子模型之border边框 盒子模型之padding内边距 部分标签自带外边距或内边距 综合代码实现 颜色赋值 三原色: 红绿蓝 RGB RedGreenBlue …

【2022秋招面经】——深度学习

文章目录请写出常用的损失函数&#xff0c;平方损失、交叉熵损失、softmax损失函数和hinge1. 0-1 损失函数2. 绝对值损失函数3. 平方损失函数4. log 对数损失函数5. 指数损失函数&#xff08;exponential loss&#xff09;6. Hinge 损失函数7. 感知损失(preceptron loss)函数8.…

网课查题接口系统使用教程

网课查题接口系统使用教程 本平台优点&#xff1a;免费查题接口搭建 多题库查题、独立后台、响应速度快、全网平台可查、功能最全&#xff01; 1.想要给自己的公众号获得查题接口&#xff0c;只需要两步&#xff01; 2.题库&#xff1a;题库后台http://daili.jueguangzhe.cn/…

使用微服务实现多设备自动调度

在实现app自动化过程中&#xff0c;有时候我们需要将多个手机中的任务&#xff0c;按照某种规则进行调度&#xff0c;这时仅仅使用移动端的脚本就无法完成了&#xff0c;需要配合使用微服务来完成。下面就举个例子来实际说明如何使用。 需求 假设我们有100台手机做任务&#…

计算机毕业设计(附源码)python疫情下的学生出入管理系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

云IDE产品介绍

前言 CSDN开发云官网发布了最新产品【云IDE】产品&#xff01;【云IDE】将提供一键秒级构建云开发环境&#xff0c;是专为开发者打造的一款低代码开发产品&#xff0c;云端预制了常见的开发环境&#xff0c;无需下载安装&#xff0c;一键创建项目&#xff0c;灵活配置代码仓和云…

【数据库05】玩转SQL的高阶特性

前 言 &#x1f349; 作者简介&#xff1a;半旧518&#xff0c;长跑型选手&#xff0c;立志坚持写10年博客&#xff0c;专注于java后端 ☕专栏简介&#xff1a;相当硬核&#xff0c;黑皮书《数据库系统概念》读书笔记&#xff0c;讲解&#xff1a; 1.数据库系统的基本概念(数据…

22.10.31补卡 22CCPC桂林C题

Problem - C - Codeforces 这题题解是请教了学长之后才做出来的, 若是想看题解请看http://t.csdn.cn/unAyg 本篇文章只作为做题记录 写了一天半...感觉自己是不太适合写区域赛的题了, 还是多学学算法和数论好了 ---------------------------------------------------------…

学习笔记-NTLM中继

NTLM中继 免责声明 本文档仅供学习和研究使用,请勿使用文中的技术源码用于非法用途,任何人造成的任何负面影响,与本人无关. NTLM hash 分为 NTLMv1 NTLMv2 NTLMv2 session 三种&#xff0c;NTLMv2 的强度比 NTLMv1 强了不少 &#xff0c;我们在实战中&#xff0c;如果获得的是 …

【Android Studio学习】第一篇、制作一个拥有登录和注册功能的简易APP

目录 第一部分、前言 1、目标效果 2、准备知识 第二部分、详细步骤 1、新建Empty工程 ​2、添加资源文件 3、搭建注册界面 4、搭建登录界面 5、编写注册界面和登录界面的代码 6、设置APP初始界面 7、连接手机&#xff0c;编译工程 第三部分、总结 1、参考资料 2、…

基于反馈技术的宽带低噪声放大器的设计

低噪声放大器是通信、雷达、电子对抗及遥控遥测系统中的必不可少的重要部件&#xff0c;它位于射频接收系统的前端&#xff0c;主要功能是对天线接收到的微弱射频信号进行线性放大&#xff0c;同时抑制各种噪声干扰&#xff0c;提高系统的灵敏度。特别是随着通信、电子对抗、微…