数据结构与算法02-排序算法

介绍

排序算法是计算机科学中被广泛研究的一个课题。历时多年,它发展出了数十种算法,这些
算法都着眼于一个问题:如何将一个无序的数字数组整理成升序?先来学习一些“简单排序”,它们很好懂,但效率不如其他排序算法。主打一个循序渐进👏

冒泡排序🐳

假设要对[4, 2, 7, 1, 3]进行排序。它现在是无序的,我们的目标是产生一个包含相同元素、升序的数组。
第 1 步:首先,比较 4 和 2。如图可见它们的顺序是错的
在这里插入图片描述
第 2 步:交换它们的位置
第 3 步:比较 4 和 7:
在这里插入图片描述
依次类推,每一次轮回过后,未排序的值中最大的那个都会“冒”到正确的位置上。

用python实现

def bubble_sort(list):
    unsorted_until_index = len(list) - 1
    sorted = False
    while not sorted:
        sorted = True
        for i in range(unsorted_until_index):
            if list[i] > list[i+1]:
                sorted = False
                list[i], list[i+1] = list[i+1], list[i]
        unsorted_until_index = unsorted_until_index - 1

list = [65, 55, 45, 35, 25, 15, 10]
bubble_sort(list)
print(list)

输出:
[10, 15, 25, 35, 45, 55, 65]

效率

冒泡排序的执行步骤可分为两种。

  • 比较:比较两个数看哪个更大。
  • 交换:交换两个数的位置以使它们按顺序排列
    如果数组不只是随机打乱,而是完全反序,在这种最坏的情况下,每次比较过后都得进行一
    次交换。
    现在把两种步骤放在一起来看。一个含有 10 个元素的数组,需要:
    9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + 1 = 45 次比较,以及 45 次交换,共 90 步。
    效率太低了😓。元素量呈倍数增长,步数却呈指数增长,如下表所示:
    在这里插入图片描述
    因此描述冒泡排序效率的大 O 记法,是 O(N 2)。
    规范一些来说:用 O(N 2)算法处理 N 个元素,大约需要 N 2步。
    O(N 2)算法是比较低效的,随着数据量变多,其步数也剧增,如下图所示:
    在这里插入图片描述
  • 嵌套循环
function hasDuplicateValue(array) {
        var steps = 0;
        for (var i = 0; i < array.length; i++) {
          for (var j = 0; j < array.length; j++) {
            steps++;
            if (i !== j && array[i] == array[j]) {
              return true;
            }
          }
        }
        console.log(steps);
        return false;
      }

      hasDuplicateValue([1,2,3])

嵌套循环算法的效率就是 O(N^2)。一旦看到嵌套循环,你就应该马上想到 O(N2)

改进

以下时间复杂度:其大 O 记法是 O(N)

function hasDup(array){
        var steps = 0;
        var existsNumbers = [];
        for (let i = 0; i < array.length; i++) {
            steps++;
            if(existsNumbers[array[i]]===undefined){
                existsNumbers[array[i]] = 1;
            }else{
                return true;
            }
        }
        console.log(steps);
        return false;
      }

执行 hasDuplicateValue([1,2,3])的话,你会看到输出为 3,跟元素个数一致。

选择排序👈

冒泡排序算法,其效率是 O(N 2)。现在我们再来探索另一种排序算法,选择排序:

步骤

(1) 从左至右检查数组的每个格子,找出值最小的那个。在此过程中,我们会用一个变量来记住检查过的数字的最小值(事实上记住的是索引,但为了看起来方便,下图就直接写出数值)。
如果一个格子中的数字比记录的最小值还要小,就把变量改成该格子的索引。
在这里插入图片描述
(2) 知道哪个格子的值最小之后,将该格与本次检查的起点交换。第 1 次检查的起点是索引 0,第2此起点时索引1
在这里插入图片描述
(3) 重复第(1) (2)步,直至数组排好序

效率

选择排序的步骤可分为两类:比较和交换,也就是在每轮检查中把未排序的值跟该轮已遇到的最小值做比较,以及将最小值与该轮起点的值交换以使其位置正确。
但每轮的交换最多只有 1 次。如果该轮的最小值已在正确位置,就无须交换,否则要做 1 次交换。相比之下,冒泡排序在最坏情况(完全逆序)时,每次比较过后都要进行 1 次交换。
在这里插入图片描述
选择排序的大 O 记法为 O(N2),跟冒泡排序一样!🙋

因为:大 O 记法不包含一般数字,除非是指数。
例如:当数据量少于某个值时,O(N2)是比 O(100N)要快的,但过了这个值之后,O(100N)便反超 O(N 2),并一直保持优势!
在这里插入图片描述

这就是大 O 记法忽略常数的原因。大 O 记法只表明,对于不同分类,存在一临界点,在这
一点之后,一类算法会快于另一类,并永远保持下去。至于这个点在哪里,大 O 并不关心。

插入排序✍

我们已经学过两种排序算法:冒泡排序和选择排序。虽然它们的效率都是 O(N 2),但其实选择排序比冒泡排序快一倍。现在来学第三种排序算法——插入排序。

在最坏的情况里,插入排序的时间复杂度跟冒泡排序、选择排序一样,都是 O(N2)

效率

插入排序包含 4 种步骤:移除、比较、平移和插入。要分析插入算法的效率,就得把每种步骤都统计一遍。
在数组完全逆序的最坏情况下,我们每一轮都要将 temp_value 左侧的所有值与temp_value 比较。因为那些值全都大于 temp_value,所以每一轮都要等到空隙移到最左端才能结束。
在第一轮,temp_value 为索引 1 的值,由于 temp_value 左侧只有一个值,所以最多进行一次比较。到了第二轮,最多进行两次比较,以此类推。到最后一轮时,就要拿 temp_value 以外的所有值与其进行比较。换言之,如果数组有 N 个元素,则最后一轮中最多进行 N - 1 次比较。
在这里插入图片描述

总结

懂得区分最好、平均、最坏情况,是为当前场景选择最优算法以及给现有算法调优以适应环
境变化的关键。记住,虽然为最坏情况做好准备十分重要,但大部分时间我们面对的是平均情况。

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

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

相关文章

最佳实践:REST API 的 HTTP 请求参数

HTTP 请求中的请求参数解释 当客户端发起 HTTP 请求 时&#xff0c;它们可以在 URL 末尾添加请求参数&#xff08;也叫查询参数或 URL 参数&#xff09;来传递数据。这些参数以键值对的形式出现在 URL 中&#xff0c;方便浏览和操作。 请求参数示例 以下是一些带有请求参数的…

springboot基本使用十二(PageHelper分页查询)

引入依赖&#xff1a; <dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version>1.3.0</version> </dependency> 通个PageHelper.startPage(page,pageSize)方…

SpringBoot的第二大核心AOP系统梳理

目录 1 事务管理 1.1 事务 1.2 Transactional注解 1.2.1 rollbackFor 1.2.2 propagation 2 AOP 基础 2.1 AOP入门 2.2 AOP核心概念 3. AOP进阶 3.1 通知类型 3.2 通知顺序 3.3 切入点表达式 execution切入点表达式 annotion注解 3.4 连接点 1 事务管理 1.1 事务…

20.Redis之缓存

1.什么是缓存&#xff1f; Redis 最主要的用途,三个方面:1.存储数据(内存数据库)2.缓存 【redis 最常用的场景】3.消息队列【很少见】 缓存 (cache) 是计算机中的⼀个经典的概念. 在很多场景中都会涉及到. 核⼼思路就是把⼀些常⽤的数据放到触⼿可及(访问速度更快)的地⽅, ⽅…

一维时间序列信号的改进小波降噪方法(MATLAB R2021B)

目前国内外对于小波分析在降噪方面的方法研究中&#xff0c;主要有小波分解与重构法降噪、小波阈值降噪、小波变换模极大值法降噪等三类方法。 (1)小波分解与重构法降噪 早在1988 年&#xff0c;Mallat提出了多分辨率分析的概念&#xff0c;利用小波分析的多分辨率特性进行分…

Facebook开户|Facebook做落地页的标准和建议

哈喽呀家人们下午好~今天Zoey来跟大家带来Facebook做落地页的标准和建议&#xff01;需要的家人建议点赞收藏啦&#xff01;&#xff01;用户通过点击你的推广链接、搜索引擎搜索结果页面的快照链接、社交媒体中的网页链接、电子邮件中的链接等进入你网站的特定页面&#xff0c…

Microsoft的Copilot现已登陆Telegram

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

AdroitFisherman模块测试日志(2024/5/28)

测试内容 测试AdroitFisherman分发包中Base64Util模块。 测试用具 Django5.0.3框架&#xff0c;AdroitFisherman0.0.29 项目结构 路由设置 总路由 from django.contrib import admin from django.urls import path,include from Base64Util import urls urlpatterns [path…

OrangePi AIpro--新手上路

目录 一、SSH登录二、安装VNC Sevice&#xff08;经测试Xrdp远程桌面安装不上&#xff09;2.1安装xface桌面2.2 配置vnc服务2.2.1 设置vnc server6-8位的密码2.2.2 创建vnc文件夹&#xff0c;写入xstartup文件2.2.3 给xstartup文件提高权限2.2.4 在安装产生的vnc文件夹创建xsta…

北京仁爱堂李艳波主任如何预约挂号?

北京仁爱堂擅长治疗神经系统疾病&#xff0c;例如&#xff1a;痉挛性斜颈&#xff0c;特发性震颤&#xff0c;眼球震颤&#xff0c;帕金森&#xff0c;眼球震颤等。 北京仁爱堂国医馆是一所集治疗、 预防、保健、养生于一体的传统中医诊所&#xff0c;具有精湛技术和丰富经验的…

ad18学习笔记20:焊盘设置Solder Mask Expansion(阻焊层延伸)

【AD18新手入门】从零开始制造自己的PCB_ad18教程-CSDN博客 Altium Designer绘制焊盘孔&#xff08;Pad孔&#xff09;封装库的技巧&#xff0c;包括原理图封装和PCB封装_哔哩哔哩_bilibili 默认的焊盘中间是有个过孔的&#xff0c;单层焊盘&#xff08;表贴烛盘&#xff09;…

怎么使用Python代码在图片里面加文字

在Python中&#xff0c;给图片添加文字可以使用Pillow库&#xff08;PIL的一个分支&#xff09;&#xff0c;它是一个强大的图像处理库。如果你还没有安装Pillow&#xff0c;可以通过pip安装&#xff1a; pip install Pillow下面使用一个简单的示例&#xff0c;演示如何使用Pi…

算法(十四)动态规划

算法概念 动态规划&#xff08;Dynamic Programming&#xff09;是一种分阶段求解的算法思想&#xff0c;通过拆分问题&#xff0c;定义问题状态和状态之间的关系&#xff0c;使得问题能够以递推&#xff08;分治&#xff09;的方式去解决。动态规划中有三个重点概念&#xff…

工厂数字化!数据治理是基础

数据治理是基础 在当今的工业生产中&#xff0c;数字化转型已成为企业提升竞争力的必由之路。然而&#xff0c;数字化转型并非一蹴而就&#xff0c;它需要战略驱动、数据治理和数据智能的协同发展。本文将围绕如何进行数字化、数据治理的内涵以及数据治理作为数字化转型基础的原…

AI预测体彩排3采取888=3策略+和值012路一缩定乾坤测试5月31日预测第7弹

今天继续基于8883的大底进行测试&#xff0c;今天继续测试&#xff0c;好了&#xff0c;直接上结果吧~ 首先&#xff0c;888定位如下&#xff1a; 百位&#xff1a;8,6,7,5,9,3,1,0 十位&#xff1a;5,7,6,4,2,9,1,0 个位&#xff1a;9,8,7,6,…

设计模式在芯片验证中的应用——迭代器

一、迭代器设计模式 迭代器设计模式(iterator)是一种行为设计模式&#xff0c; 让你能在不暴露集合底层表现形式 &#xff08;列表、 栈和树等数据结构&#xff09; 的情况下遍历集合中所有的元素。 在验证环境中的checker会收集各个monitor上送过来的transactions&#xff0…

java家政上门系统源码,App端采用uniapp开发编写,可打包H5 、微信小程序、微信公众号、Android、IOS等。

家政上门系统是一种通过互联网或移动应用平台&#xff0c;为用户提供在线预约、下单、支付和评价家政服务的系统。该系统整合了家政服务资源&#xff0c;使用户能够便捷地找到合适的服务人员&#xff0c;同时也为家政服务人员提供了更多的工作机会。 本套家政上门系统源码&…

eclipse如何debug

步骤1&#xff1a;双击显示行数的数字来设置断点 步骤2&#xff1a;点击debug 步骤3&#xff1a;在弹出的窗口点击switch 步骤4&#xff1a;就可以调试了&#xff0c;右边是查看数据的&#xff0c;点击上面的图标进行下一步 步骤5&#xff1a;退出debug 步骤6&#xff1a;…

Github 2024-06-01 开源项目日报Top10

根据Github Trendings的统计,今日(2024-06-01统计)共有10个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目5Jupyter Notebook项目2TypeScript项目1Go项目1Shell项目1Lua项目1Kong:云原生API网关与AI能力 创建周期:3482 天开发语言:Lua协议…

易联众智能自动办理平台,AI赋能让数字政务服务“触手可及”

“城乡居民参保怎么办”“要去XX省工作了,帮我办理异地就医备案”……通过口语化的文字、语音提问,易联众智能自动办理平台的AI助理都可以准确理解对话,并依据政策文件给出详细回答,人机对话像聊天一样轻松。 近日,宁德市民王先生高兴地说:“过去办理医保业务不懂流程,容易走弯…