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

news2024/11/18 9:32:16

介绍

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

冒泡排序🐳

假设要对[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 次比较。
在这里插入图片描述

总结

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

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

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

相关文章

Git系列:rev-parse 使用技巧

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

vmware workstation 17.0.0 ubuntu删除快照导致无法启动的问题打不开磁盘xxxxxxx或它所依赖的某个快照磁盘

在使用vmware workstation的时候 在我删除多余的快照的时候&#xff0c;发现删除快照后打不开虚拟机了&#xff0c; 提示&#xff1a; 打不开此虚拟磁盘的父磁盘打不开磁盘“D:\Virtual Machines\Ubuntu 64 位\Ubuntu 64 位-000003.vmdk”或它所依赖的某个快照磁盘。模块“Dis…

曾巩,散文的艺术与哲思

曾巩&#xff0c;字子固&#xff0c;世称南丰先生&#xff0c;南丰&#xff08;今江西&#xff09;人&#xff0c;生于北宋真宗天禧三年&#xff08;公元1019年&#xff09;&#xff0c;卒于北宋元丰六年&#xff08;公元1083年&#xff09;&#xff0c;享年64岁。他是中国北宋…

低功耗蓝牙模块在便携式医疗设备上的应用前景

随着科技的不断发展&#xff0c;医疗设备的便携性和智能化已经成为了一种趋势。在这个背景下&#xff0c;低功耗蓝牙模块(Bluetooth Low Energy,简称BLE)作为一种先进的无线通信技术&#xff0c;正逐渐在便携式医疗设备中发挥着越来越重要的作用。本文美迅物联网MesoonRF将探讨…

Debian和ubuntu 嵌入式的系统的 区别

随着开源操作系统的日益流行&#xff0c;Debian和Ubuntu这两个基于Linux的发行版本成为了众多开发者和系统管理员的首选。它们各自拥有独特的优势和特点&#xff0c;那么&#xff0c;在选择时&#xff0c;哪一个更适合你呢&#xff1f;接下来&#xff0c;我们将深入探讨两者的关…

计算机网络——如何保证 TCP 传输的可靠性

TCP 是传输层上的协议&#xff0c;它是可靠的&#xff0c;面向连接的。 概括 1. 设置传输格式&#xff0c;包括分为 TCP 段、使用校验和、使用序列号 2. 数据丢失之后的重传&#xff0c;超时重传、快速重传、SACK 选择确认、D-SACK 重复选择确认 3. 流量控制&#xff0c;控…

python编程:SQLite 管理图片数据库

在本博客中&#xff0c;我们将介绍如何使用 wxPython 和 sqlite3 模块构建一个 GUI 应用程序&#xff0c;该程序可以遍历指定文件夹中的所有图片&#xff0c;并将其信息存储到 SQLite 数据库中。 C:\pythoncode\new\InputImageOFFolderTOSqlite.py 项目简介 我们的目标是创建…

linux可观测性ebpf(一) ----------- 环境搭建

参考书籍 开发环境 Ubuntu 18.04.6 LTS (GNU/Linux 5.4.0-150-generic x86_64) 1.1 下载内核源码 cd /usr/src/ sudo git clone -b v5.4 https://github.com/torvalds/linux.git1.2 下载书中代码 git clone https://github.com/bpftools/linux-observability-with-bpf1.3 编…

Java常用API(三)

一、Arrays类 1.定义 Arrays是一个用于操作数组的工具类。 2.常用方法 1.toString方法 public class Demo {public static void main(String[] args) {//toString 将数组变成字符串int[] arr {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};System.out.println(Arrays.toString(arr));…

arduino 与 nodeMcu 之间的通信

一、前言 当在 arduino 板子处理好了传感器的数据应该发送给远程服务器这时候就需要用 nodeMcu 了&#xff0c;但是怎么把 arduino 的数据发送到 nodeMcu 呢&#xff0c;这就是本文要实现的。 两个板子之间通信很简单&#xff0c;直接使用 arduino IDE 提供的 Serial.println…

Java web应用性能分析之【压测工具ab】

常用的性能测试工具有&#xff1a;JMeter、loadRunner、ab&#xff1b;对于开发人员来说用的多的是免费的Jmeter和ab&#xff0c;对于测试来说可能用收费的商业软件loadRunner多。在这里我们就说说ab压测工具&#xff0c;因为ab基本满足web接口测试要求&#xff0c;jmeter后面再…

详解生成式人工智能的开发过程

回到机器学习的“古老”时代&#xff0c;在您可以使用大型语言模型&#xff08;LLM&#xff09;作为调优模型的基础之前&#xff0c;您基本上必须在所有数据上训练每个可能的机器学习模型&#xff0c;以找到最佳&#xff08;或最不糟糕&#xff09;的拟合。 开发生成式人工智能…

学习网站地址汇总

本文用于记录学习路上遇到问题&#xff0c;各位大神的分享笔记&#xff0c;内容包括数据库的安装卸载&#xff0c;基础使用&#xff0c;sql语句编写&#xff0c;计算机网络知识等&#xff0c;属于知识大杂烩 1.动态行转列&#xff1a;https://www.cnblogs.com/gaizai/p/375329…

【设计模式深度剖析】【B】【结构型】【对比】| 主要区别包装的不同

&#x1f448;️上一篇:享元模式 回 顾&#xff1a;结构型设计模式 1.代理模式&#x1f448;️ 2.装饰器模式&#x1f448;️ 3.适配器模式&#x1f448;️ 4.组合模式&#x1f448;️ 5.桥接模式&#x1f448;️ 6.外观模式&#x1f448;️ 7.享元模式&#x…

Java操作Excel文档进行读取和写入

目录 读出Excel文档 写入Excel文档 读出Excel文档 使用EasyExcel读取Excel文件: 需要在maven项目中导入EasyExcel依赖 <!-- EasyExcel依赖包 --> <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><v…

信号稳定,性能卓越!德思特礁鲨系列MiMo天线正式发布!

作者介绍 礁鲨系列天线&#xff0c;以其独特的外观设计和强大的性能&#xff0c;成为德思特Panorama智能天线家族的最新成员。这款天线不仅稳定提供5G、WIFI和GNSS信号&#xff0c;更能在各类复杂环境中展现出卓越的性能。它的设计灵感来源于海洋中的礁鲨&#xff0c;象征着力量…

STM32G030C8T6:EEPROM读写实验(I2C通信)--M24C64

本专栏记录STM32开发各个功能的详细过程&#xff0c;方便自己后续查看&#xff0c;当然也供正在入门STM32单片机的兄弟们参考&#xff1b; 本小节的目标是&#xff0c;系统主频64 MHZ,采用高速外部晶振&#xff0c;实现PB11,PB10 引脚模拟I2C 时序&#xff0c;对M24C08 的EEPRO…

低代码开发平台(Low-code Development Platform)的模块组成部分

低代码开发平台&#xff08;Low-code Development Platform&#xff09;的模块组成部分主要包括以下几个方面&#xff1a; 低代码开发平台的模块组成部分可以按照包含系统、模块、菜单组织操作行为等维度进行详细阐述。以下是从这些方面对平台模块组成部分的说明&#xff1a; …

翻译《The Old New Thing》- What a drag: Dragging a virtual file (HGLOBAL edition)

What a drag: Dragging a virtual file (HGLOBAL edition) - The Old New Thing (microsoft.com)https://devblogs.microsoft.com/oldnewthing/20080318-00/?p23083 Raymond Chen 2008年03月18日 拖拽虚拟文件&#xff08;HGLOBAL 版本&#xff09; 现在我们已经对简单的数据…

MySQL之创建高性能的索引(七)

创建高性能的索引 InnoDB和MyISAM的数据分布对比 聚簇索引和非聚簇索引欸度数据分布有区别&#xff0c;以及对应的主键索引和二级索引的数据分布也有区别&#xff0c;通常会让人感到困扰和意外。来看看InnoDB和MyISAM时如何存储下面这个表的: CREATE TABLE layout_test ( co…