排序补充之快排的三路划分法

news2024/9/23 17:22:57

排序补充之快排的三路划分法

在这里插入图片描述

快排性能的关键点分析:

决定快排性能的关键点是每次单趟排序后,key对数组的分割,如果每次选key基本⼆分居中,那么快 排的递归树就是颗均匀的满⼆叉树,性能最佳。但是实践中虽然不可能每次都是⼆分居中,但是性能 也还是可控的。但是如果出现每次选到最⼩值/最⼤值,划分为0个和N-1的⼦问题时,时间复杂度为 O(N^2),数组序列有序时就会出现这样的问题,我们前⾯已经⽤三数取中或者随机选key解决了这个问 题,也就是说我们解决了绝⼤多数的问题,但是现在还是有⼀些场景没解决(数组中有⼤量重复数据 时),类似⼀下代码。

// 数组中有多个跟key相等的值
int a[] = { 6,1,7,6,6,6,4,9 };
int a[] = { 3,2,3,3,3,3,2,3 };
// 数组中全是相同的值
int a[] = { 2,2,2,2,2,2,2,2 };

三路划分算法思想讲解:

当⾯对有⼤量跟key相同的值时,三路划分的核⼼思想有点类似hoare的左右指针和lomuto的前后指针 的结合。核⼼思想是把数组中的数据分为三段【⽐key⼩的值】 【跟key相等的值】【⽐key⼤的 值】,所以叫做三路划分算法。

  1. key默认取left位置的值。
  2. left指向区间最左边,right指向区间最后边,cur指向left+1位置。
  3. cur遇到⽐key⼩的值后跟left位置交换,换到左边,left++,cur++。
  4. cur遇到⽐key⼤的值后跟right位置交换,换到右边,right–。
  5. cur遇到跟key相等的值后,cur++。
  6. 直到cur > right结束

代码如下:

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
void PrintArray(int* a, int n)
{
 for (int i = 0; i < n; ++i)
 {
 printf("%d ", a[i]);
 }
 printf("\n");
}
void Swap(int* p1, int* p2)
{
 int tmp = *p1;
 *p1 = *p2;
 *p2 = tmp;
}

typedef struct
{
 int leftKeyi;
 int rightKeyi;
}KeyWayIndex;
// 三路划分
KeyWayIndex PartSort3Way(int* a, int left, int right)
{
 int key = a[left];
 // left和right指向就是跟key相等的区间
 // [开始, left-1][left, right][right+1, 结束]
 int cur = left + 1;
 while (cur <= right)
 {
 // 1、cur遇到⽐key⼩,⼩的换到左边,同时把key换到中间位置
 // 2、cur遇到⽐key⼤,⼤的换到右边
if (a[cur] < key)
 {
 Swap(&a[cur], &a[left]);
 ++cur;
 ++left;
 }
 else if (a[cur] > key)
 {
 Swap(&a[cur], &a[right]);
 --right;
 }
 else
 {
 ++cur;
 }
 }
 KeyWayIndex kwi;
 kwi.leftKeyi = left;
 kwi.rightKeyi = right;
 return kwi;
}

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

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

相关文章

数学建模笔记(四):熵权

背景&基本思想介绍 在实际的评价类问题中&#xff0c;在前面所说的层次分析法以及Topsis法中&#xff0c;指标权重的确定往往是通过主观的评价得来的&#xff0c;如果在没有专家的情况下&#xff0c;我们自己的权重分配往往可能带有一定的主观性&#xff0c;有没有一种可以…

linux系统离线安装docker并配置阿里云镜像源

制作docker.service文件 创建docker.service文件 cd /etc/systemd/system/ touch docker.service编辑docker.service文件 vim docker.service// 注意&#xff0c;将其中的ip地址&#xff0c;改成您的服务器地址&#xff0c;其它参数不用改。 //--insecure-registry192.168.8…

代码随想录算法day22 | 回溯算法part04 | 491.递增子序列,46.全排列,47.全排列 II

491.递增子序列 本题和大家做过的 90.子集II 非常像&#xff0c;但又很不一样&#xff0c;很容易掉坑里。 力扣题目链接(opens new window) 给定一个整型数组, 你的任务是找到所有该数组的递增子序列&#xff0c;递增子序列的长度至少是2。 示例: 输入: [4, 6, 7, 7]输出: [[4,…

【学习笔记】时间序列模型(ARIMA)

文章目录 前言一、时间序列时间序列数据 二、ARIMA 模型大纲模型前提平稳性检验 差分整合移动平均自回归模型 ARIMA(p,q,d)自回归模型 (AR( p ))移动平均模型 (MA( q ))自回归移动平均模型(ARMA(p,q))差分自回归移动平均模型 ARIMA(p,d,q) 确定 p&#xff0c;q结果分析和模型检…

SpringBoot集成kafka-消费者批量消费消息

SpringBoot集成kafka-消费者批量消费消息 1、消费者2、生产者3、application.yml配置文件4、实体类5、生产者发送消息测试类6、测试6.1、测试启动生产者6.2、测试启动消费者 1、消费者 设置批量接收消息 package com.power.consumer;import org.apache.kafka.clients.consume…

IC-Light容器构建详细指南

一、介绍 IC-Light 是一个操纵图像照明的项目&#xff0c;能够让一张普普通通的照片焕发光彩。 IC-Light&#xff0c;全称为“Imposing Consistent Light”&#xff0c;是一款由 AI 图像处理专家张吕敏&#xff08;ControlNet 的作者&#xff09;精心开发的创新工具。主要用于…

启用 UFW 防火墙后如何打开 80 和 443 端口?

UFW&#xff08;Uncomplicated Firewall&#xff09;是一款 Linux 系统上用户友好的管理防火墙规则的工具。它简化了控制网络流量的过程&#xff0c;使用户更容易开放或阻止端口。 本文将引导您使用 UFW 打开端口 80 (HTTP) 和 443 (HTTPS) 端口。您将了解如何启用这些端口&am…

uni-app项目搭建和模块介绍

工具:HuilderX noed版本:node-v17.3.1 npm版本:8.3.0 淘宝镜像:https://registry.npmmirror.com/ 未安装nodejs可以进入这里https://blog.csdn.net/a1241436267/article/details/141326585?spm1001.2014.3001.5501 目录 1.项目搭建​编辑 2.项目结构 3.使用浏览器运行…

华为Cloud连接配置

Cloud(云)连接意思为本地电脑和eNSP中的虚拟的VRP系统连接的 配置Cloud 先添加UDP 再添加需要使用的网卡 网卡建议使用虚拟机的网卡&#xff0c;如果没有虚拟机也可以使用其他网卡&#xff0c;自己设定一下IP就行 端口映射设置 配置R1 [R1]int e0/0/0 [R1-Ethernet0/0/0]ip …

B. 不知道该叫啥

题意&#xff1a;求长度为n的数列方案数&#xff0c;数列需满足两个条件&#xff1a;1.均为正整数。2.相邻两个数乘积不能超过m 思路&#xff1a;考虑dp。 设表示前i个点以j结尾的方案数&#xff0c;则有&#xff1a; 可以得出&#xff1a; 双指针数论分块解决。把每个m/i相…

一个下载镜像非常快的网站--华为云

1、镜像的下载飞速 链接&#xff1a;mirrors.huaweicloud.com/ubuntu-releases/24.04/ 下载一个的ubuntu24.04的镜像文件&#xff0c;5.7G的大文件&#xff0c;不到1分钟就下完毕了&#xff0c; 比起阿里云下载的速度600K/S,这个速度是100多倍。 非常的神速&#xff0c;非常…

如何选择高品质科研实验室用太阳光模拟器

概述 太阳光模拟器是一种能够模拟太阳光照射条件的设备&#xff0c;主要用于实验室环境中对太阳能相关材料和设备进行性能测试。这类模拟器能够提供与自然太阳光谱相似的光照&#xff0c;同时还能精确控制光照强度和照射角度&#xff0c;以满足不同测试需求。 对于被归类为太…

Leetcode 104. 二叉树的最大深度 C++实现

Leetcode 104. 二叉树的最大深度 问题&#xff1a;给定一个二叉树root&#xff0c;返回其最大深度。 二叉树的最大深度是指从根节点到最远叶子节点的最长路径上的节点数。 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* …

【Linux篇】Linux的用户和权限

目录 1. 认识Linux的root用户&#xff08;超级管理员&#xff09; 1.1 介绍 1.2 su命令和exit命令 1.3 sudo命令 为普通用户配置sudo认证 2. 用户与用户组 2.1 用户组管理 2.2 用户管理 2.3 getent命令 3. 查看权限控制信息 3.1 认知权限信息 3.2 rwx含义 r&#x…

巴恩斯利蕨数学公式及源码实现——JavaScript版

为什么要写这篇文章 本篇接《张侦毅&#xff1a;巴恩斯利蕨数学公式及源码实现》。之前文章中源码的编程语言用的是Java&#xff0c;JDK的版本为8&#xff0c;现在我的JDK版本已经升级到22了&#xff0c;在新版本JDK中&#xff0c;原来的JApplet方法已经被废弃&#xff0c;不能…

云原生之全链路分布式跟踪系统 Zipkin和SkyWalking

贪多嚼不烂 Pinpoint 就不对比了 参考 APM系统简单对比(zipkin,pinpoint和skywalking) springcloud 看云 Zipkin和SkyWalking都是流行的分布式跟踪系统&#xff0c;但它们的设计和实现有明显的不同。 以下是它们之间的一些对比&#xff1a; 数据存储&#xff1a; Zipk…

Linux与Windows的文件与目录操作API汇总整理

文件和目录操作是编程中非常基础且常用的部分&#xff0c;涉及到文件的创建、读写、删除以及目录的创建、删除等功能。下面是文件和目录操作的汇总整理&#xff0c;包括常见的API及其用途&#xff1a; 文件操作 POSIX 系统&#xff08;如 Linux 和 macOS&#xff09; 打开文件…

Python二级知识点

在阅读之前&#xff0c;感谢大家的关注和点赞。祝你们都能心想事成、健健康康。 一.数据流程图 一般这道题是经常考的&#xff0c;有向箭头--->表示数据流。圆圈○表示加工处理。 二.字典如何比较大小 字典类型是如何比较大小的呢&#xff0c;是使用字典的键来比较大小&…

Python 使用everything的相关模块,创建极其快速的文件搜索和管理工具

在这篇博客中&#xff0c;我将分享如何使用 Python 的 everytools库构建一个简单的文件搜索和管理工具。这个工具允许用户搜索文件、查看文件路径、导出文件信息到 Excel&#xff0c;以及生成配置文件。 C:\pythoncode\new\everythingtools.py 项目概述 这个工具的主要功能包…

mysql binlog 全量与增量备份

mysql binlog 全量与增量备份 mysql binlog常用操作 https://blog.csdn.net/xyy1028/article/details/124446625 mysqldump mysqlbinlog 增量备份 mysql的增量备份 https://blog.51cto.com/u_16213572/10976496 mysql全量备份与增量备份 — vip https://blog.51cto.com/hehe1…