冒泡排序,选择排序,插入排序,归并排序,快速排序五种排序方法

一 冒泡排序

冒泡排序是一种简单的排序算法,工作原理是通过重复交换相邻的元素,将较大的元素“冒泡”到数组的末端。以下是冒泡排序的基本步骤和示例代码:

1 冒泡排序步骤

  • 从数组的开始位置,依次比较相邻的两个元素。
  • 如果前一个元素大于后一个元素,则交换它们。
  • 一轮比较后,最大的元素会被放到数组的最后位置。
  • 重复以上步骤,对剩余的元素继续排序,直到整个数组有序。

2 示例代码

function bubbleSort(arr) {const len = arr.length;for (let i = 0; i < len - 1; i++) {for (let j = 0; j < len - 1 - i; j++) {if (arr[j] > arr[j + 1]) {// 交换[arr[j], arr[j + 1]] = [arr[j + 1], arr[j]];}}}return arr;
}// 使用示例
const array = [5, 3, 8, 4, 2];
const sortedArray = bubbleSort(array);
console.log(sortedArray); // 输出: [2, 3, 4, 5, 8]

3 时间复杂度

最坏和平均情况下的时间复杂度是 O(n²),最好情况下(数组已经有序)是 O(n)。

二 选择排序(Selection Sort)

1 原理:

选择排序(Selection Sort)是一种简单直观的排序算法,适合小规模的数据排序。它的基本思想是将待排序的数组分为已排序和未排序两部分,然后不断从未排序部分中选择最小(或最大)的元素,将其放到已排序部分的末尾。

时间复杂度:O(n²)

2 示例代码:

arr= [64, 25, 12, 22, 11]

  1. 第 一次循环
  • 未排序部分:[64, 25, 12, 22, 11]
  • 找到最小值 11,交换 11 和 64
  • 结果:[11, 25, 12, 22, 64]
  1. 第 二次循环
  • 未排序部分:[25, 12, 22, 64]

  • 找到最小值 12,交换 12 和 25

  • 结果:[11, 12, 25, 22, 64]

  1. 第三次循环
  • 未排序部分:[25, 22, 64]
  • 找到最小值 22,交换 22 和 25
  • 结果:[11, 12, 22, 25, 64]
  1. 第四次循环
  • 未排序部分:[25, 64]
  • 找到最小值 25,无需交换
  • 结果:[11, 12, 22, 25, 64]

最后,数组已完全排序。

function selectionSort(arr) {const len = arr.length;for (let i = 0; i < len - 1; i++) {let minIndex = i;for (let j = i + 1; j < len; j++) {if (arr[j] < arr[minIndex]) {minIndex = j;}}// 交换[arr[i], arr[minIndex]] = [arr[minIndex], arr[i]];}return arr;
}

三. 插入排序(Insertion Sort)

1 原理:

将数组分为已排序和未排序两部分,从未排序部分逐个取出元素,插入到已排序部分的合适位置。

  1. 初始化:将第一个元素视为已排序部分。
  2. 遍历未排序部分:从第二个元素开始,逐个取出未排序部分的元素。
  3. 插入位置:将当前元素与已排序部分的元素进行比较,找到合适的位置进行插入。
  4. 移动元素:将已排序部分的元素向右移动,腾出位置插入当前元素。
  5. 重复:重复步骤2到4,直到所有元素排序完成。

时间复杂度:O(n²)

2 示例代码:

function insertionSort(arr) {const len = arr.length;for (let i = 1; i < len; i++) {const key = arr[i];let j = i - 1;while (j >= 0 && arr[j] > key) {arr[j + 1] = arr[j];j--;}arr[j + 1] = key;}return arr;
}

四. 归并排序(Merge Sort)

1 原理:

采用分治法,将数组分成两半,分别排序后再合并。

  1. 分解:将待排序数组递归地分成两半,直到每个部分只包含一个元素(一个元素本身是有序的)。
  2. 合并:将两个已排序的部分合并成一个更大的已排序部分。
  3. 重复:直到所有部分合并完成。

时间复杂度:O(n log n)

2 示例代码:

function mergeSort(arr) {if (arr.length <= 1) return arr;const mid = Math.floor(arr.length / 2);const left = mergeSort(arr.slice(0, mid));const right = mergeSort(arr.slice(mid));return merge(left, right);
}function merge(left, right) {const result = [];let i = 0, j = 0;while (i < left.length && j < right.length) {if (left[i] < right[j]) {result.push(left[i++]);} else {result.push(right[j++]);}}return result.concat(left.slice(i)).concat(right.slice(j));
}

五. 快速排序(Quick Sort)

1 原理:

选择一个“基准”元素,分区使得比基准小的元素在左边,比基准大的元素在右边,然后递归排序。

  1. 选择基准:从数组中选择一个元素作为基准(pivot)。
  2. 分区:将数组重新排列,使得所有比基准小的元素在基准的左侧,所有比基准大的元素在基准的右侧。
  3. 递归排序:对基准左侧和右侧的子数组递归地应用快速排序。

平均情况下 O(n log n),最坏情况下 O(n²)。

假设我们有数组 [10, 80, 30, 90, 40, 50, 70]:

  • 选择基准:假设选择最后一个元素 70 作为基准。
  • 分区: 将数组重新排列为 [10, 30, 40, 50, 70, 90, 80],此时 70 处于正确位置。
  • 递归排序: 对 [10, 30, 40, 50] 和 [90, 80] 进行快速排序。

继续进行分区和递归,最终得到已排序的数组 [10, 30, 40, 50, 70, 80, 90]。

2 示例代码:

function quickSort(arr) {if (arr.length <= 1) return arr;const pivot = arr[arr.length - 1];const left = [];const right = [];for (let i = 0; i < arr.length - 1; i++) {if (arr[i] < pivot) {left.push(arr[i]);} else {right.push(arr[i]);}}return [...quickSort(left), pivot, ...quickSort(right)];
}

  1. 冒泡排序

通过多次遍历数组,比较并交换相邻元素,简单但效率较低。

优点:

  • 实现简单,易于理解。
  • 适合小规模数据。

缺点:

  • 效率低,时间复杂度为 O(n²)。
  • 在大型数据集上性能不佳。
  1. 选择排序

每次选择未排序部分中的最小元素放到已排序部分,时间复杂度为 O(n²)。

优点:

  • 简单易实现。
  • 不需要额外的存储空间,空间复杂度为 O(1)。

缺点:

  • 时间复杂度为 O(n²),效率较低。
  • 不稳定排序,可能改变相同元素的相对位置。
  1. 插入排序

逐个将元素插入到已排序部分的正确位置,适合小规模数据,时间复杂度为 O(n²)。

优点:

  • 在部分有序数据上表现良好,时间复杂度为 O(n)。
  • 实现简单,适合小规模数据。
  • 稳定排序。

缺点:

  • 最坏情况下时间复杂度为 O(n²)。
  • 对大规模数据不够高效。
  1. 归并排序

采用分治法,将数组分为两半递归排序,然后合并,时间复杂度为 O(n log n)。

优点:

  • 时间复杂度为 O(n log n),效率较高。
  • 稳定排序,适合处理大量数据。

缺点:

  • 需要额外的存储空间,空间复杂度为 O(n)。
  • 实现较复杂。
  1. 快速排序

选择基准元素,将数组分为小于和大于基准的两部分,递归排序,平均时间复杂度为 O(n log n)。

优点:

  • 平均时间复杂度为 O(n log n),效率高。
  • 原地排序,空间复杂度为 O(log n)。

缺点:

  • 最坏情况下时间复杂度为 O(n²),但可以通过随机化基准元素来减少概率。
  • 不稳定排序。

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

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

相关文章

工程师 - Windows下打开PowerShell和CMD Prompt的若干方法

打开PowerShell 在Windows中&#xff0c;你可以通过以下几种方式来打开PowerShell&#xff1a; 1. 开始菜单&#xff08;Start Menu&#xff09;&#xff1a;点击“开始”按钮&#xff0c;然后在搜索栏中输入“PowerShell”。在搜索结果中&#xff0c;选择“Windows PowerShell…

【若依RuoYi-Vue | 项目实战】帝可得后台管理系统(二)

文章目录 一、人员管理1、需求说明2、生成基础代码&#xff08;1&#xff09;创建目录菜单&#xff08;2&#xff09;添加数据字典&#xff08;3&#xff09;配置代码生成信息&#xff08;4&#xff09;下载代码并导入项目 3、人员列表改造&#xff08;1&#xff09;基础页面&a…

最新免费域名申请

在互联网时代&#xff0c;每个码农都想拥有一个免费的域名&#xff0c;方便开发调试&#xff0c;也可用作自己网站等。如何申请一个免费的域名&#xff0c;时间上先错过了freenom&#xff0c;后面又错过nic.eu.org申请(现在申请时间长且很难通过)&#xff0c;直到最近又有免费的…

计算机网络(八) —— Udp协议

目录 一&#xff0c;再谈端口号 1.1 端口号 1.2 netsta命令 二&#xff0c;UDP协议 2.1 关于UDP 2.2 Udp协议格式 2.3 Udp协议特点 2.4 Udp的缓冲区 一&#xff0c;再谈端口号 http协议本质是“请求 - 响应”形式的协议&#xff0c;但是应用层需要先将数据交给传输层&…

pthread_cond_signal 和pthread_cond_wait

0、pthread_join()函数作用&#xff1a; pthread_join() 函数会一直阻塞调用它的线程&#xff0c;直至目标线程执行结束&#xff08;接收到目标线程的返回值&#xff09;&#xff0c;阻塞状态才会解除。如果 pthread_join() 函数成功等到了目标线程执行结束&#xff08;成功获取…

(Python) Structured Streaming读取Kafka源实时处理图像

Producer.py import cv2 from kafka import KafkaProducer import os import os.path as osp# Kafka 服务器地址 bootstrap_servers [xxx.xxx.xxx.xxx:9092] #terminal运行ifconfig可以查看localhost# 创建 Kafka 生产者 producer KafkaProducer(bootstrap_serversbootstrap…

什么是 GPT?通过图形化的方式来理解 Transformer 架构

Predict, sample, repeat 预测、取样、重复 GPT 是 Generative Pre-trained Transformer 的缩写。首个单词较为直接&#xff0c;它们是用来生成新文本的机器人。“Pre-trained” 指的是模型经历了从大量数据中学习的过程&#xff0c;这个词暗示了该模型还有进一步在特定任务中…

开关柜设备红外检测数据集

开关柜设备红外检测数据集 包含以下2个数据文件&#xff1a; /train&#xff1a;训练集 /valid&#xff1a;验证集 /test&#xff1a;测试集 README.txt&#xff1a;数据说明 【数据说明】检测目标以Pascal VOC格式进行标注&#xff0c;对每个图像进行以下预处理&#xff0c;统…

极度精简 Winows11 系统镜像!Tiny11 2311下载 - 支持苹果 M 芯片 Mac 安装 (ARM 精简版)!

最新推出的 Tiny11 是一款极端精简版 Windows 11 系统镜像&#xff0c;针对苹果 M 芯片 Mac 用户&#xff08;ARM 架构&#xff09;提供良好支持。Tiny11 内置了众多优化特性&#xff0c;如更小的安装体积和更快的启动速度&#xff0c;特别适合有特殊需求或老机型的用户。用户可…

华为HarmonyOS地图服务 7- 在地图上绘制标记

场景介绍 本章节将向您介绍如何在地图的指定位置添加标记以标识位置、商家、建筑等。 点标记用来在地图上标记任何位置,例如用户位置、车辆位置、店铺位置等一切带有位置属性的事物。Map Kit提供的点标记功能(又称 Marker)封装了大量的触发事件,例如点击事件、长按事件、…

基于YOLO算法的网球运动实时分析-击球速度测量-击球次数(附源码)

这个项目通过分析视频中的网球运动员来测量他们的速度、击球速度以及击球次数。该项目使用YOLO&#xff08;You Only Look Once&#xff09;算法来检测球员和网球&#xff0c;并利用卷积神经网络&#xff08;CNNs&#xff09;来提取球场的关键点。此实战项目非常适合提升您的机…

VsCode C语言 SDL包配置 2024.9

写这篇文章的起因是&#xff0c;最近我需要使用 SDL 包&#xff0c;我懒得下载V-studio ,所以直接在VsCode 里配置C环境。我搞了好几个小时&#xff0c;啥都弄好了&#xff0c;但是一直被下面几个问题缠绕导致demo启动不了&#xff0c;现在我记录一下这奇葩的解决过程。所有路径…

Qt Debugging帮助文档

Qt中给断点添加条件&#xff1a; 示例1&#xff1a; 当i10时&#xff0c;程序中断 但不知道为什么&#xff0c;46行的条件没有生效&#xff0c;47行的条件生效了 给断点添加忽略次数&#xff1a; 在程序停止之前忽略该断点200次。 Breakpoints (Debugging with GDB)

Apache Doris 实践

Apache Doris 实践 官方使用指南&#xff1a;https://doris.incubator.apache.org/zh-CN/docs/install/source-install/compilation-with-docker/ 手动安装 下载二进制安装包https://apache-doris-releases.oss-accelerate.aliyuncs.com/apache-doris-2.1.5-bin-x64.tar.gz …

华润电力最新校招社招润择认知能力测评:逻辑推理数字计算语言理解高分攻略

​ 尊敬的求职者们&#xff0c; 在您准备加入华润电力这个大家庭之前&#xff0c;了解其招聘测评的详细流程和要求是至关重要的。以下是我们为您整理的测评系统核心内容&#xff0c;希望对您的求职之旅有所帮助。 测评系统概览 华润电力的招聘测评系统旨在全面评估求职者的认…

机器学习04-逻辑回归(python)-02原理与损失函数

1. 逻辑回归概念 逻辑回归&#xff08;Logistic Regression&#xff09; 是一种 分类模型&#xff0c;主要用于解决 二分类问题&#xff08;即分成两类&#xff0c;如是否通过、是否患病等&#xff09;。逻辑回归的目标是根据输入的特征预测一个 概率&#xff0c;这个概率值介于…

计算机毕业设计hadoop+spark+hive新能源汽车销售数据分析系统 二手车销量分析 新能源汽车推荐系统 可视化大屏 汽车爬虫 机器学习

《HadoopSparkHive新能源汽车销售数据分析系统》开题报告 一、选题背景与意义 1.1 选题背景 随着全球对环境保护意识的增强和能源结构的转型&#xff0c;新能源汽车市场迅速崛起。新能源汽车的销售数据不仅反映了市场趋势和消费者偏好&#xff0c;还为企业决策、政府监管和政…

微服务——网关登录校验(一)

1.网关登录校验 微服务中的网关登录校验是微服务架构中常见的一种安全机制&#xff0c;用于在请求到达微服务之前&#xff0c;对用户的身份进行验证&#xff0c;确保只有合法的用户才能访问相应的服务。 在微服务架构中&#xff0c;每个微服务都是独立部署的&#xff0c;它们之…

(C++17) optional 的 3 种用法

文章目录 *️⃣前言*️⃣3 种主流用法1️⃣函数返回值2️⃣函数参数3️⃣类成员 ⭐END&#x1f31f;跋&#x1f31f;交流方式 *️⃣前言 在 C17 中标准化了 std::optional。该类型可以容纳一种类型&#xff0c;且判断是否有无。 若使用的标准在低于 C17 则可以使用 Abseil 的…

浅谈递推法

递推法 递推法是一种数学方法&#xff0c;用于通过利用已知的初始条件和递推关系来计算要求中的每一项。以数列来举例&#xff0c;在递推法中&#xff0c;它的思想很简单&#xff1a;我们首先知道数列的第一项&#xff08;初始条件&#xff09;&#xff0c;然后通过一个规律&a…