当前位置: 首页 > news >正文

排序算法记录(冒泡+快排+归并)

文章目录

    • 前言
    • 冒泡排序
    • 快速排序
    • 归并排序

前言

冒泡 + 快排 + 归并,这三种排序算法太过经典,但又很容易忘了。虽然一开始接触雀氏这些算法雀氏有些头大,但时间长了也还好。主要是回忆这些算法干了啥很耗时间。

如果在笔试时要写一个o(nlogn)的排序算法,如果不能立刻写出 快排或者归并,未免有些太浪费时间了。

故写这篇文章用于记录

tip: 一下内容均实现升序排序

冒泡排序

所谓冒泡,就是每一轮都排出一个最大的元素,把他丢在末尾。
在这里插入图片描述
如上图所示,5个元素的数组我们需要5轮遍历,每次遍历可以排出一个当前遍历区域内最大的元素

而确定最大元素的方法起始也很简单。每一次遍历,我们都和其前一个元素对比,也就是比较arr[j - 1]arr[j]。如果 arr[j - 1] > arr[j],则交换,否则不变。这样的比较方式让算法趋向于将大的元素向右边送,直到将最大的元素送到最右侧

当第一轮排序完成后,第二轮排序的范围则被缩小。因为已知最大元素在最右侧,那么无需遍历最右侧元素。

第三轮同理,无需遍历倒数第二个元素。以此类推

import java.util.*;public class Main {public static void main(String[] args) {// 冒泡int N;Scanner sc = new Scanner(System.in);N = sc.nextInt();int[] arr = new int[N];for (int i = 0; i < N; ++i) {arr[i] = sc.nextInt();}// sort 核心for (int i = 0; i < N; ++i) {for (int j = 1; j < N - i; ++j) {if (arr[j - 1] > arr[j]) {int tmp = arr[j];arr[j] = arr[j - 1];arr[j - 1] = tmp;}}}// printfor (int i = 0; i < N; ++i) {System.out.print(arr[i]);if (i < N - 1) System.out.print(" ");}}
}

快速排序

所谓快速排序,和俄罗斯套娃很像。我们想要快速排序俄罗斯套娃,可以做如下操作:

  1. 选出一个基准娃
  2. 遍历所有娃,小的放左边,大的放右边
  3. 如果两侧的娃不用排序,则终止
  4. 对基准娃左右两侧的娃娃们做1,2,3操作

快排也是类似的

在这里插入图片描述
不同的是,俄罗斯套娃是将别的元素摆放到基准娃的两侧;快排是通过交换左右两侧元素,定位到base的位置

import java.util.*;public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int N = sc.nextInt();int[] arr = new int[N];for (int i = 0; i < N; ++i) {arr[i] = sc.nextInt();}// quickSortquickSort(arr, 0, N - 1);// printfor (int i = 0; i < N; ++i) {System.out.print(arr[i]);if (i < N - 1) System.out.print(" ");}}public static void quickSort(int[] arr, int lef, int rig) {if (lef >= rig) return;int base = arr[lef];int lp = lef, rp = rig;while (lp < rp) {// 右指针寻找到<base的数for (; rp > lp && arr[rp] >= base; --rp);arr[lp] = arr[rp];// 左指针寻找到>base的数for (; rp > lp && arr[lp] <= base; ++lp);arr[rp] = arr[lp];}arr[lp] = base;quickSort(arr, lef, lp - 1);quickSort(arr, lp + 1, rig);}
}

tip: 快排有一些注意点需要强调

  1. 递归终止条件,快排起始也是递归,是递归就需要终止条件。本题递归的终止条件就是lef >= rig,排序范围左侧端点不在右侧端点左边
  2. for (; rp > lp && arr[rp] >= base; --rp); 这个for相当于右侧小人,寻找 小于 base的数。因为是寻找小于,因此循环条件是 >= base就一直寻找
  3. 如果base是数组第一个元素,那么先走动的必须是右侧小人。因为数组最左侧元素,我们用base进行备份,先走右侧小人覆盖最左侧元素不会丢失base信息

归并排序

归并排序就有点蛋疼了,虽然代码极少(相对来说),但思维量如果不熟悉分治的情况下还是比较大的。

本文并非专业的介绍文章,感兴趣的读者可以详细阅读这篇文章

归并排序大致思路如下:

  1. 往死里拆分数组,具体拆分的方式就是对半拆
  2. 当拆分到不能再拆,局部合并

其中,mergeSort干的任务是对lef ~ right范围内的数组归并排序,merge属于归并排序中,的部分。

因为递归的原因,上层递归栈merge数组,以mid为临界区域,left ~ midmid + 1 ~ right这两段数组,内部元素都是局部递增的。这个原因很简单,因为递归的特性,回溯到上层栈,底层栈一定把功能实现好

这有点类似于甩锅,我排序全部数组太累了,于是找两个小弟,一个归并排序左边,一个排序右边。我不许用关心小弟怎么排序,我只需要知道,等小弟回来(回溯),我就只需要排序两个有序数组

所以要实现merge的功能,起始就是对两段有序数组进行排序

假设两段数组分别是arr1, arr2(实际上只有arr,为了方便叙述,我们说成两段)具体的排法是双指针遍历。

对于arr1, arr2。谁的元素大,谁就把元素按序存储到tmp中。

import java.util.*;public class Main {private static int[] tmp;public static void main(String[] args) {Scanner sc = new Scanner(System.in);int N = sc.nextInt();int[] arr = new int[N];tmp = new int[N];for (int i = 0; i < N; ++i) {arr[i] = sc.nextInt();}// mergemergeSort(arr, 0, N - 1);// printfor (int i = 0; i < N; ++i) {System.out.print(arr[i]);if (i < N - 1)System.out.print(" ");}sc.close();}public static void mergeSort(int[] arr, int left, int right) {if (left < right) {int mid = (left + right) / 2;mergeSort(arr, left, mid);mergeSort(arr, mid + 1, right);merge(arr, left, right);}}public static void merge(int[] arr, int left, int right) {int mid = (left + right) / 2;        int lp = left, rp = mid + 1, k = left;while (lp <= mid && rp <= right) {if (arr[lp] < arr[rp]) tmp[left++] = arr[lp++];else tmp[left++] = arr[rp++]; }while (lp <= mid) tmp[left++] = arr[lp++]; // 左区间没迭代完while (rp <= right) tmp[left++] = arr[rp++]; // 右区间没迭代完for (; k <= right; ++k) arr[k] = tmp[k]; // copy}
}

另外,值得一提的是,归并是上述三种排序中最快的。冒泡,快排都没有AC

相关文章:

排序算法记录(冒泡+快排+归并)

文章目录 前言冒泡排序快速排序归并排序 前言 冒泡 快排 归并&#xff0c;这三种排序算法太过经典&#xff0c;但又很容易忘了。虽然一开始接触雀氏这些算法雀氏有些头大&#xff0c;但时间长了也还好。主要是回忆这些算法干了啥很耗时间。 如果在笔试时要写一个o(nlogn)的…...

简单聊聊如何更优雅地初始化对象:构造函数、Builder模式和静态工厂方法比较

大家好&#xff0c;我是G探险者。 在平时的java编程中&#xff0c;你肯定会有过对一些实体对象进行初始化的set操作&#xff0c;有的对象的属性较少可能还好点&#xff0c;当一个对象拥有许多属性时&#xff0c;通常的初始化方式可能显得笨拙而不直观&#xff0c;代码写的很不…...

跳过mysql权限验证来修改密码-GPT纯享版

建议重新配置一遍&#xff0c;弄成功好多次了&#xff0c;每次都出bug&#xff0c;又要重新弄&#xff0c;不是过期就是又登不进去了&#xff0c;我服了 电脑配置MySQL环境&#xff08;详细&#xff09;这个哥们的10min配完&#xff0c;轻轻松松&#xff0c; 旧方法&#xff…...

Vue3快速上手(十七)Vue3之状态管理Pinia

一、简介 Pinia官网:https://pinia.vuejs.org/zh/ 从官网截图里可以直接看到,pinia是一个vuejs的状态(数据)管理工具。功能性同vuex。logo是小菠萝。它是一个集中式状态管理工具。就是将多个组件共用的数据管理起来,重复利用。有点类似缓存的意思。 二、Pinia环境搭建 …...

时序预测 | Matlab实现BiTCN-GRU双向时间卷积神经网络结合门控循环单元时间序列预测

时序预测 | Matlab实现BiTCN-GRU双向时间卷积神经网络结合门控循环单元时间序列预测 目录 时序预测 | Matlab实现BiTCN-GRU双向时间卷积神经网络结合门控循环单元时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.Matlab实现BiTCN-GRU双向时间卷积神经网络结…...

学习笔记Day14:Linux下软件安装

软件安装 Anaconda 所有语言的包(package)、依赖(dependency)和环境(environment)管理器&#xff0c;类似应用商店 Conda < Miniconda < Anaconda&#xff08;有交互界面&#xff09; Linux下Miniconda即可 安装Miniconda 搜索北外/清华miniconda镜像网站&#xff…...

【CXL协议-事务层之CXL.io(3)】

3.1 CXL.io CXL.io 为 I/O 设备提供非一致的加载/存储接口。 图 14 显示了 CXL.io 事务层在 Flex Bus 分层结构中的位置。 交易类型、交易数据包格式、基于信用的流量控制、虚拟通道管理和交易排序规则遵循PCIe定义&#xff1b; 请参阅 有关详细信息&#xff0c;请参阅 PCI Ex…...

如何自己构建 Ollama 模型

如何自己构建 Ollama 模型 0. 引言1. 下载原始模型2. 创建 Modelfile 文件3. 构建 Ollama 模型4. 运行自构建的 Ollama 模型 0. 引言 针对模型新出的大模型&#xff0c;可能 Ollama Models Library 不提供&#xff0c;或者会在今后的某个时点提供。还有可能 Ollama Models Lib…...

5.84 BCC工具之tcpretrans.py解读

一,工具简介 tcpretrans工具追踪内核TCP重传函数,以显示这些重传的详细信息。 它专门用于追踪TCP重传事件。在网络通信中,重传是由于数据包丢失、损坏或延迟到达而需要重新发送的情况。tcpretrans通过利用Linux内核中的BPF(Berkeley Packet Filter)机制,能够实时捕获和…...

从0到1实现RPC | 03 重载方法和参数类型转换

一、存在的问题 1.重载方法在当前的实现中还不支持&#xff0c;调用了会报错。 2.类型转换也还存在问题。 假设定义的接口如下&#xff0c;参数是float类型。 在Provider端接受到的是一个Double类型&#xff0c;这是因为web应用接收的请求后处理的类型。 在反射调用的时候就会…...

Matlab之已知2点绘制长度可定义的射线

目的&#xff1a;在笛卡尔坐标系中&#xff0c;已知两个点的位置&#xff0c;绘制过这两点的射线。同时射线的长度可以自定义。 一、函数的参数说明 输入参数&#xff1a; PointA&#xff1a;射线的起点&#xff1b; PointB&#xff1a;射线过的零一点&#xff1b; Length&…...

虚拟机安装Linux系统,FinalShell远程连接Linux

1.虚拟机安装CentOS系统 2. 查看CentOS系统的ip地址 3. FinalShell远程连接Linux 3.虚拟机快照&#xff08;存档&#xff09; 确保虚拟机关机&#xff0c;找到快照模拟器 恢复快照...

MacOS Xcode 使用LLDB调试Qt的 QString

环境&#xff1a; MacOS&#xff1a; 14.3Xcode&#xff1a; Version 15.0Qt&#xff1a;Qt 6.5.3 前言 Xcode 中显示 预览 QString 特别不方便, 而Qt官方的 lldb 脚本debugger/lldbbridge.py一直加载失败&#xff0c;其他第三方的脚本都 不兼容当前的 环境。所以自己研究写…...

C/C++代码性能优化——编程实践

1. 编程实践 在一些关键的地方&#xff0c;相应的编程技巧能够给性能带来重大提升。 1.1. 参数传递 传递非基本类型时&#xff0c;使用引用或指针&#xff0c;这样可以避免传递过程中发生拷贝。参数根据是否需要返回&#xff0c;相应加上const修饰&#xff0c;代码更安全&am…...

JVM—内存可见性

什么是可见性 可见性&#xff1a;一个线程对共享变量值的修改,能够及时地被其他线程看到共享变量&#xff1a;如果一个变量在多个线程的工作内存中都存在副本,那么这个变量就是这几个线程的共享变量 Java内存模型(JMM) Java内存模型(Java Memory Model)描述了Java程序中各种…...

VScode手动安装vsix格式插件,提示安装插件与code版本不兼容问题

问题描述: vscode手动按装插件提示"插件不兼容code版本 原因方案:修改安装包内的package.json文件中的版本号与vscode版本号对应即可 解决步骤 以(adpyke.codesnap-1.3.4.vsix)安装包为例 手动安装vscode弹出 无法安装扩展“adpyke.codesnap-1.3.4”&#xff0c;它与 …...

K8S Storage

概述 一般情况下&#xff0c;K8S中的Pod都不应该将数据持久化到Pod中&#xff0c;因为Pod可能被随时创建和删除&#xff08;扩容或缩容&#xff09;&#xff0c;即便是StatefulSet或Operator的Pod&#xff0c;也都不建议在Pod里存放数据&#xff0c;可以将数据持久化到Host上。…...

Day54-nginx限速-访问日志-错误日志精讲

Day54-nginx限速-访问日志-错误日志精讲 测试请求限制连接限制&#xff08;limit_conn&#xff09;下载速度限制(limit_rate) ngx_http_core_module综合配置1.Nginx状态监控1.1 Nginx status介绍1.2 Nginx status配置1.3 基本状态数据如下所示&#xff1a;&#xff08;注意本地…...

SQL经典面试题

这里写目录标题 1 背概念2 学例子 1 背概念 1 事务 事务是最小的不可在分的工作单元&#xff0c;事务的操作要么同时成功,要么同时失败。 ACID: 原子性、一致性、隔离性、持久性 2 约束 主键约束&#xff1b;外键约束&#xff08;少用&#xff0c;会增加程序的耦合性&#xff…...

Java基础知识总结(14)

map集合 /* java.util.Map接口中常用的方法 1、Map和Collection 没有继承关系 2、Map集合以key和value的方式存储数据&#xff1a;键值对key和valuea都是引用数据类型key和value都是存储对象的内存地址key起到主导地位&#xff0c;value是key的一个附属品 3、Map接口中常用的方…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩

目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

第25节 Node.js 断言测试

Node.js的assert模块主要用于编写程序的单元测试时使用&#xff0c;通过断言可以提早发现和排查出错误。 稳定性: 5 - 锁定 这个模块可用于应用的单元测试&#xff0c;通过 require(assert) 可以使用这个模块。 assert.fail(actual, expected, message, operator) 使用参数…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

Swagger和OpenApi的前世今生

Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章&#xff0c;二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑&#xff1a; &#x1f504; 一、起源与初创期&#xff1a;Swagger的诞生&#xff08;2010-2014&#xff09; 核心…...

Web 架构之 CDN 加速原理与落地实践

文章目录 一、思维导图二、正文内容&#xff08;一&#xff09;CDN 基础概念1. 定义2. 组成部分 &#xff08;二&#xff09;CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 &#xff08;三&#xff09;CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 &#xf…...

云原生安全实战:API网关Kong的鉴权与限流详解

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关&#xff08;API Gateway&#xff09; API网关是微服务架构中的核心组件&#xff0c;负责统一管理所有API的流量入口。它像一座…...

08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险

C#入门系列【类的基本概念】&#xff1a;开启编程世界的奇妙冒险 嘿&#xff0c;各位编程小白探险家&#xff01;欢迎来到 C# 的奇幻大陆&#xff01;今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类&#xff01;别害怕&#xff0c;跟着我&#xff0c;保准让你轻松搞…...

Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)

引言 工欲善其事&#xff0c;必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后&#xff0c;我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集&#xff0c;就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...

c++第七天 继承与派生2

这一篇文章主要内容是 派生类构造函数与析构函数 在派生类中重写基类成员 以及多继承 第一部分&#xff1a;派生类构造函数与析构函数 当创建一个派生类对象时&#xff0c;基类成员是如何初始化的&#xff1f; 1.当派生类对象创建的时候&#xff0c;基类成员的初始化顺序 …...

【Linux】Linux安装并配置RabbitMQ

目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的&#xff0c;需要先安…...