从二叉树角度来理解快速排序

快速排序就是个二叉树的前序遍历

                                                                                        ——————labuladong

快速排序的逻辑

快速排序是先将一个元素排好序,然后再将剩下的元素排好序

若要对 nums[lo..hi] 进行排序,我们先找一个分界点 p,通过交换元素使得 nums[lo..p-1] 都小于等于 nums[p],且 nums[p+1..hi] 都大于 nums[p],然后递归地去 nums[lo..p-1] 和 nums[p+1..hi] 中寻找新的分界点,最后整个数组就被排序了。

从二叉树的视角,我们可以把子数组 nums[lo..hi] 理解成二叉树节点上的值,srot 函数理解成二叉树的遍历函数。

partition 函数每次都将数组切分成左小右大两部分,最后形成的这棵二叉树是一棵二叉搜索树

但谈到二叉搜索树的构造,那就不得不说二叉搜索树不平衡的极端情况,极端情况下二叉搜索树会退化成一个链表,导致操作效率大幅降低。所以我们要对初始数组进行随机性处理

快速排序的代码框架

void sort(int[] nums, int lo, int hi) {/****** 前序遍历位置 ******/// 通过交换元素构建分界点 pint p = partition(nums, lo, hi);/************************/sort(nums, lo, p - 1);sort(nums, p + 1, hi);
}

我们与二叉树的前序遍历代码框架进行对比:

/* 二叉树遍历框架 */
void traverse(TreeNode root) {if (root == null) {return;}/****** 前序位置 ******/print(root.val);/*********************/traverse(root.left);traverse(root.right);
}

快速排序的代码实现

class Quick {public static void sort(int[] nums) {// 为了避免出现耗时的极端情况,先随机打乱数组元素顺序shuffle(nums);// 排序整个数组(原地修改)sort(nums, 0, nums.length - 1);}// 私有的递归排序函数,使用快速排序算法对数组进行排序 private static void sort(int[] nums, int lo, int hi) {if (lo >= hi) {return; // 递归结束条件,当 lo 大于等于 hi 时,子数组已经有序}// 对 nums[lo..hi] 进行切分// 使得 nums[lo..p-1] <= nums[p] < nums[p+1..hi]int p = partition(nums, lo, hi); // 获取切分点 p// 对切分点左右两边的子数组分别进行递归排序sort(nums, lo, p - 1);sort(nums, p + 1, hi);}// 切分函数,用于确定切分点并重新排列数组元素private static int partition(int[] nums, int lo, int hi) {int pivot = nums[lo]; // 选择第一个元素作为切分元素int i = lo + 1, j = hi; // 定义两个指针 i 和 j// 使用双指针将数组划分为两部分,一部分小于等于pivot,一部分大于pivotwhile (i <= j) {while (i < hi && nums[i] <= pivot) {i++; // 移动左指针直到找到一个大于pivot的元素}while (j > lo && nums[j] > pivot) {j--; // 移动右指针直到找到一个小于等于pivot的元素}// 交换左右指针所指向的元素,保证左边小于等于pivot,右边大于pivotif (i >= j) {break; // 当左右指针相遇时退出循环}swap(nums, i, j); // 交换 nums[i] 和 nums[j]}// 将pivot放到合适的位置,即使得左边元素小于等于pivot,右边元素大于pivotswap(nums, lo, j); // 将切分元素放到最终位置return j; // 返回切分元素的下标}// 洗牌算法,将输入的数组随机打乱private static void shuffle(int[] nums) {Random rand = new Random(); // 创建随机数生成器int n = nums.length;for (int i = 0 ; i < n; i++) {// 生成 [i, n - 1] 的随机数int r = i + rand.nextInt(n - i); // 生成 [i, n - 1] 范围内的随机数swap(nums, i, r); // 将第i个元素与第r个元素交换}}// 原地交换数组中的两个元素private static void swap(int[] nums, int i, int j) {int temp = nums[i]; // 临时保存 nums[i]nums[i] = nums[j];  // 将 nums[j] 放到 nums[i] 的位置nums[j] = temp;      // 将临时保存的 nums[i] 放到 nums[j] 的位置}
}

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

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

相关文章

Centos7 双机单网卡安装 OpenStack

虚拟机配置 1&#xff1a;准备虚拟机2台&#xff0c;配置如下 openstack master----192.168.20.205 2cpu&#xff0c;8G内存&#xff0c;200G硬盘&#xff0c;网络桥接方式--静态IP----单网卡 node1计算节点---192.168.20.215 2cpu&#xff0c;8G内存&#xff0c;200G硬盘&a…

专业120+总分400+海南大学838信号与系统考研高分经验海大电子信息与通信

今年专业838信号与系统120&#xff0c;总分400&#xff0c;顺利上岸海南大学&#xff0c;这一年的复习起起伏伏&#xff0c;但是最后还是坚持下来的&#xff0c;吃过的苦都是值得&#xff0c;总结一下自己的复习经历&#xff0c;希望对大家复习有帮助。首先我想先强调一下专业课…

scrapy的概念作用和工作流程

1. scrapy的概念 Scrapy是一个Python编写的开源网络爬虫框架。它是一个被设计用于爬取网络数据、提取结构性数据的框架。 Scrapy 使用了Twisted[twɪstɪd]异步网络框架&#xff0c;可以加快我们的下载速度。 Scrapy文档地址&#xff1a;http://scrapy-chs.readthedocs.io/zh_…

05 双向链表

目录 1.双向链表 2.实现 3.OJ题 4.链表和顺序表对比 1. 双向链表 前面写了单向链表&#xff0c;复习一下 无头单向非循环链表&#xff1a;结构简单&#xff0c;一般不会单独用来存数据。实际中更多作为其他数据结构的子结构&#xff0c;如哈希桶、图的邻接等。另外这种结构在…

dubbo和eureka的区别

dubbo可以作为客户端&#xff0c;也可以作为服务端&#xff0c;因此他内置了很多序列化框架可供选择&#xff0c;通过配置可以进行选择。默认是hession&#xff0c;还有gson&#xff0c;fastJson&#xff0c;jdk自带的序列化。 eureka只能作为服务端&#xff0c;他序列要与客户…

解析MySQL生产环境CPU使用率过高的排查与解决方案

引言 在生产环境中&#xff0c;MySQL作为一个关键的数据库组件&#xff0c;其性能对整个系统的稳定性至关重要。然而&#xff0c;有时候我们可能会遇到MySQL CPU使用率过高的问题&#xff0c;这可能导致系统性能下降&#xff0c;应用页面访问减慢&#xff0c;甚至影响到用户体…

编译与运行环境(C语言)

文章目录 前言编译环境编译链接 运行环境 前言 C语言代码的实现&#xff0c;存在两种不同的环境。 第一种是翻译环境&#xff0c;在这个环境中&#xff0c;源代码被转换为可执行的二进制指令。 翻译环境即我们日常使用编译器&#xff0c;将一个 " mission.c " 的文件…

软件包管理:在CentOS 7中部署Tengine

目录 下载&#xff1a; 方法一&#xff1a; 方法二&#xff1a; 部署&#xff1a; 实验操作 下载&#xff1a; 方法一&#xff1a; 1、打开浏览器搜索tengine并点击官网 2、选择需要安装的版本并复制链接链接 标题栏处可以更改为中文界面 下滑选择版本单击下载 在远程连…

Matlab神经网络

Matlab神经网络 资料 拟合神经网络fitnet里面的函数 选择神经网络输入输出处理函数 MATLAB 创建神经网络模型的patternnet和newff函数区别 MATLAB中patternnet函数返回的网络结构中各个参数的含义 神经网络对象属性 径向基函数神经网络&#xff08;RBFNN&#xff09;详解 RBF网…

Python字符串:基础要点与实践应用

文章目录 一、Python字符串1.介绍2.与C语言字符串比较2.1 相同点2.2 不同点 3.创建Python字符串3.1 使用单引号3.2 使用双引号3.3 使用三引号 二、访问字符串中的值1.索引方式2.截取方式 三、Python 转义字符1.续行符\(在行尾时)2.反斜杠符号\\3.单引号\4.双引号\"5.响铃\…

使用Docker部署MySQL并结合内网穿透实现远程访问本地数据库

文章目录 前言1 .安装Docker2. 使用Docker拉取MySQL镜像3. 创建并启动MySQL容器4. 本地连接测试4.1 安装MySQL图形化界面工具4.2 使用MySQL Workbench连接测试 5. 公网远程访问本地MySQL5.1 内网穿透工具安装5.2 创建远程连接公网地址5.3 使用固定TCP地址远程访问 前言 本文主…

搭建nginx图片服务器

&#xff08;1&#xff09;将图片存储于/home/data/images目录&#xff1b; &#xff08;2&#xff09;配置nginx.conf user nginx; worker_processes 4;error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid;events {worker_connections 10000; }ht…

Vue3中ElementPlus组件二次封装,实现原组件属性、插槽、事件监听、方法的透传

本文以el-input组件为例&#xff0c;其它组件类似用法。 一、解决数据绑定问题 封装组件的第一步&#xff0c;要解决的就是数据绑定的问题&#xff0c;由于prop数据流是单向传递的&#xff0c;数据只能从父流向子&#xff0c;子想改父只能通过提交emit事件通知父修改。 父&a…

移动Web——平面转换-旋转

1、平面转换-旋转 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><style…

DAY32:贪心算法part2、122\55\45

贪心算法没有统一的模板&#xff0c;因此对题目的理解非常重要&#xff0c;理解题目&#xff0c;了解之后想到代码就很简单。 Leetcode: 122 买卖股票的最佳时机II 首先&#xff0c;题目中只有一支股票&#xff0c;可以一直买入卖出。而且我们只需要记录利润&#xff0c;不需…

在使用springboot框架式的的script无法通过${}来获取值

今天使用springboot框架做项目&#xff0c;想着来实现一下搜索的下拉框回显功能&#xff0c;然后就一直在报错误&#xff0c;关键是报的错误牛头不对马嘴&#xff0c;检查了一下后端代码&#xff0c;发现没什么问题&#xff0c;就把目光聚焦了.jsp页面的代码 <script type&…

主流影视网站8合一H5源码

目前影视接口完好&#xff0c;可正常观看影视。 上传即可使用 包括了 百度视频风格 PP视频风格 咪咕爱看风格 爱奇艺风格 腾讯视频风格 优酷视频风格 搜狐视频风格 B站风格 8种主流影视网站&#xff0c;喜欢那个用那个

函数类(Function Classes)和 富函数类(Rich Function Classes)

目录 函数类&#xff08;Function Classes&#xff09; 富函数类&#xff08;Rich Function Classes&#xff09; 函数类&#xff08;Function Classes&#xff09; Flink暴露了所有UDF函数的接口&#xff0c;具体实现方式为接口或者抽象类&#xff0c;例如MapFunction、Filt…

【STM32】STM32学习笔记-Unix时间戳(41)

00. 目录 文章目录 00. 目录01. Unix时间戳02. UTC/GMT03. 时间戳转换04. C 标准库 <time.h>05. 时间相关函数示例5.1 time函数5.2 gmtime函数5.3 localtime函数5.4 mktime函数5.5 ctime函数5.6 asctime函数5.7 strftime函数 06. 预留07. 附录 01. Unix时间戳 •Unix 时…

2024-macOS系统或Kail系统重——破解ZIP压缩的文件密码

2024-macOS系统或Kail系统重——破解ZIP压缩的文件密码 1. 你们有遇见这样子的情况么&#xff1a; 别人给你发的zip或者下载的zip文件&#xff0c;没有密码打不开么网上都是win系统的&#xff0c;都是没有macOS系统的&#xff0c;所以比较烦恼 2. 所以我就想到了代码&#x…