【八大排序(三)】快速排序

news2024/11/19 9:23:55

❣博主主页: 33的博客❣
▶️文章专栏分类:八大排序◀️
🚚我的代码仓库: 33的代码仓库🚚
🫵🫵🫵关注我带你了解更多排序知识

在这里插入图片描述

目录

  • 1.前言
  • 2.快速排序
    • 2.1概念
    • 2.2画图理解
    • 2.3递归代码实现
      • 2.3.1Hoare法
      • 2.3.2挖坑法
      • 2.3.3前后指针法
      • 2.3.4优化
    • 2.4非递归代码实现
  • 3.总结

1.前言

关于排序的知识,我们已经介绍了直接插入排序,希尔排序,选择排序和堆排序,这篇文章博主就继续和大家分享快速排序的知识。

2.快速排序

2.1概念

快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法,其基本思想:任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割城两个子序,左子序中的元素均小于基准值,右子序的元素均大于基准值,然后最左右子序列重复该过程,直到所有元素都排列在相应位置上为止。

2.2画图理解

选择排序

2.3递归代码实现

2.3.1Hoare法

在这里插入图片描述

 public int[] quickOrder(int[] arr){
        int p=0;
        quick(0,arr.length-1,arr);
        return arr;
    }
    private void quick(int start, int end, int[] arr) {
    if (start>=end){
        return;
    }
    int p=partionHoare(start,end,arr);
    quick(start,p-1,arr);
    quick(p+1,end,arr);
    }
    public int partionHoare(int l,int r,int[] arr){
        int tmp=l;
        while (l<r){
            while (l<r&&arr[l]<arr[tmp]){
                l++;
            }
            while (r>l&&arr[r]>arr[tmp]){
                r--;
            }
            swap(l,r,arr);
        }
        //l==r
        swap(l,tmp,arr);
        return l;
    }

2.3.2挖坑法

在这里插入图片描述

    private void quick(int start, int end, int[] arr) {
    if (start>=end){
        return;
    }
    int p=partitionHole(start,end,arr);
    quick(start,p-1,arr);
    quick(p+1,end,arr);
    }
    public int partitionHole(int l,int r,int[] arr){
        int tmp=arr[l];
        while (l<r){
            if (l<r&&arr[r]>tmp){
                r--;
            }
            arr[l]=arr[r];
            if (l<r&&arr[l]<tmp){
                l++;
            }
            arr[r]=arr[l];
        }
        arr[l]=tmp;
        return l;
    }

2.3.3前后指针法

在这里插入图片描述

private void quick(int start, int end, int[] arr) {
    if (start>=end){
        return;
    }
    int p=partition(start,end,arr);
    quick(start,p-1,arr);
    quick(p+1,end,arr);
    }
private  int partition( int left, int right,int[] array) {
        int prev = left ;
        int cur = left+1;
        while (cur <= right) {
            if(array[cur] < array[left] && array[++prev] != array[cur]) {
                swap(cur,prev,array);
            }
            cur++;
        }
        swap(prev,left,array);
        return prev;

2.3.4优化

观察上述代码,我们发现我们的基准值都是第一个元素,如果一个了比较有序的数组,我们进行快排,就可能形成当分支的树,所有我们要堆基准值进行优化,选取最左边,最右边元素和中间元素比较大小,把值为中间的作为基准元素。

   public int[] quickOrder(int[] arr){
        int p=0;
        quick(0,arr.length-1,arr);
        return arr;
    }
    private void quick(int start, int end, int[] arr) {
    if (start>=end){
        return;
    }
    if (end-start>=15){
        insertOrder(start,end,arr);
        return;
    }
    int m=mid(start,end, arr);
    swap(start,m,arr);
   
    int p=int p=partitionHole(start,end,arr);
    quick(start,p-1,arr);
    quick(p+1,end,arr);
    }
    public void insertOrder(int l,int r ,int[] arr){
        for (int i=l+1;i<=r;i++){
            int tmp=arr[i];
            int j=i-1;
            for (;j>=0;j--){
                if(arr[j]>tmp){
                    arr[j+1]=arr[j];
                }else break;
            }
            arr[j+1]=tmp;
        }
    }
    public  int mid(int l,int r,int[] arr){
       int mid=(l+r)/2;
       if (arr[l]<arr[r]){
           if(arr[mid]<arr[l]){
               return l;
           }else if (arr[mid]>arr[r]){
               return r;
           }else {
               return mid;
           }
       }else {
           //arr[l]>=arr[r]
           if (arr[mid]>arr[l]){
               return l;
           }else if (arr[mid]<arr[r]){
               return r;
           }else {
               return mid;
           }
       }
    }
    public int partitionHole(int l,int r,int[] arr){
        int tmp=arr[l];
        while (l<r){
            if (l<r&&arr[r]>tmp){
                r--;
            }
            arr[l]=arr[r];
            if (l<r&&arr[l]<tmp){
                l++;
            }
            arr[r]=arr[l];
        }
        arr[l]=tmp;
        return l;
    }   

2.4非递归代码实现

在这里插入图片描述

public int[] quickOrderNor(int[] arr){
        Stack<Integer> stack=new Stack<>();
        int s=0;
        int e=arr.length-1;
        int pivot=partitionHole(s,e,arr);
        if (pivot-1>s){
            stack.push(s);
            stack.push(pivot-1);
        }
        if (e-1>pivot){
            stack.push(pivot+1);
            stack.push(e);
        }
        while (!stack.isEmpty()){
             e=stack.pop();
             s=stack.pop();
             pivot=partitionHole(s,e,arr);
            if (pivot-1>s){
                stack.push(s);
                stack.push(pivot-1);
            }
            if (e-1>pivot){
                stack.push(pivot+1);
                stack.push(e);
            }
        }
    return arr;
    }

时间复杂度:
最好的情况下:O(N
logN)
最坏情况下:O(N^2) 逆序/有序
空间复杂度:
最好的情况下:O(logN)
最坏情况下:O(N) 逆序/有序
稳定性:不稳定
*

3.总结

快速排序是一个比较重要的排序算法,它可以用多种方法来实现,但不同方法的时间复杂度和空间复杂度。

下期预告:归并排序

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

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

相关文章

vue3 引用虚拟键盘simple-keyboard

simple-keyboard官网地址&#xff1a;https://virtual-keyboard.js.org 目前实现效果图是&#xff08;实现数字、大小写字母键盘&#xff09;&#xff1a; 1.需要先安装simple-keyboard npm install simple-keyboard --save2.封装sinpleKeyboard 组件 <!-- keyboard-bo…

24深圳杯数学建模挑战赛A题6页初步思路+参考论文+保姆级答疑!!!

问题1:单个残骸的精确位置定位 建立数学模型&#xff0c;分析如果要精准确定空中单个残骸发生音爆时的位置坐标&#xff08;经度、纬度、高程&#xff09;和时间&#xff0c;至少需要布置几台监测设备&#xff1f;假设某火箭一级残骸分离后&#xff0c;在落点附近布置了7台监测…

聊聊 ASP.NET Core 中间件(一):一个简单的中间件例子

前言&#xff1a;什么是中间件 服务器在收到 HTTP 请求后会对用户的请求进行一系列的处理&#xff0c;比如检查请求的身份验证信息、处理请求报文头、检查是否存在对应的服务器端响应缓存、找到和请求对应的控制器类中的操作方法等&#xff0c;当控制器类中的操作方法执行完成…

02 spring-boot+mybatis+elementui 的登录,文件上传,增删改查的入门级项目

前言 主要是来自于 朋友的需求 项目概况 就是一个 学生信息的增删改查 然后 具体到业务这边 使用 mybatis xml 来配置的增删改查 后端这边 springboot mybatis mysql fastjson hutool 的一个基础的增删改查的学习项目, 简单容易上手 前端这边 node14 vue element…

【C++】初识string类

一、熟悉string类 1.1 string类的由来&#xff1a; C语音中的字符串需要我们自己管理底层空间&#xff0c;容易内存泄露。而C是面向对象语音&#xff0c;所以它把字符串封装成一个string类。 C中对于string的定义为&#xff1a;typedef basic_string string; 也就是说C中的str…

Microsoft Universal Print 与 SAP 集成教程

引言 从 SAP 环境打印是许多客户的要求。例如数据列表打印、批量打印或标签打印。此类生产和批量打印方案通常使用专用硬件、驱动程序和打印解决方案来解决。 Microsoft Universal Print 是一种基于云的打印解决方案&#xff0c;它允许组织以集中化的方式管理打印机和打印机驱…

【网站项目】个性化商铺系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

int类型的取值范围(为什么负数比正数表示的范围多一位)

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;C语言基本概念 &#x1f337;追光的人&#xff0c;终会万丈光芒 目录 &#x1f3dd;1.int的基本概念&#xff1a; 空间大小&#xff1a; 有符号类型的表示形式&#xff1a; &#x1f3dd;2.…

【数据结构与算法】力扣 239. 滑动窗口最大值

题干描述 给你一个整数数组 nums&#xff0c;有一个大小为 k **的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。 返回 滑动窗口中的最大值 。 示例 1&#xff1a; 输入&#xff1a; nums [1,3,-1,-3,5,3…

PPO 学习笔记

用PPO算法求解整个神经网络在迭代过程中的梯度问题 每走一步就会得到一个新的状态&#xff0c;把这个状态传到网络里面&#xff0c;会得到一个 action&#xff0c;执行这个 action 又会到达一个新状态 policy 中由状态 st 生成动作 at&#xff0c;生成的这个 at 是由整个网络的…

【MySQL】——用户和权限管理(二)

&#x1f4bb;博主现有专栏&#xff1a; C51单片机&#xff08;STC89C516&#xff09;&#xff0c;c语言&#xff0c;c&#xff0c;离散数学&#xff0c;算法设计与分析&#xff0c;数据结构&#xff0c;Python&#xff0c;Java基础&#xff0c;MySQL&#xff0c;linux&#xf…

PotatoPie 4.0 实验教程(33) —— FPGA实现摄像头视频图像叠加

链接直达 https://item.taobao.com/item.htm?ftt&id776516984361 什么是视频水印&#xff1f; 视频水印就是图像叠加&#xff0c;跟画中画&#xff0c;或者是OSD是一样的原理&#xff0c;都是在视频的行场数据流上进行替换操作&#xff0c;比如叠加可以直接用水印图的数…

【Python小练】求斐波那契数列第n个数

题目 输出斐波那契数列第n个数。 分析 首先我们要知道&#xff0c;斐波那契数列&#xff0c;这个数列从第三位开始等于前两个数的和&#xff0c;要知道数列第n个数&#xff08;n>2&#xff09;&#xff0c;就要知道其前两相的值&#xff0c;着就需要用到递归了。来看一下吧…

Java面试重点之反射机制

一、 反射是什么&#xff1f; 允许程序在运行时查询和操作对象的类型信息。通过反射&#xff0c;程序能够在运行时获取对象的类定义信息&#xff0c;如类的名称、方法、字段、注解等&#xff0c;并且可以动态地调用对象的方法或访问其字段&#xff0c;而无需在编译时具体知道对…

【LAMMPS学习】八、基础知识(5.3)Body particles体粒子

8. 基础知识 此部分描述了如何使用 LAMMPS 为用户和开发人员执行各种任务。术语表页面还列出了 MD 术语&#xff0c;以及相应 LAMMPS 手册页的链接。 LAMMPS 源代码分发的 examples 目录中包含的示例输入脚本以及示例脚本页面上突出显示的示例输入脚本还展示了如何设置和运行各…

C语言:数据结构(双向链表)

目录 1、双向链表的结构2、顺序表和双向链表的优缺点分析3、双向链表的实现 1、双向链表的结构 注意&#xff1a;这⾥的“带头“跟前面我们说的“头节点”是两个概念&#xff0c;实际前面的在单链表阶段称呼不严谨&#xff0c;但是为了更好的理解就直接称为单链表的头节点。 带…

上位机开发PyQt(五)【Qt Designer】

PyQt5提供了一个可视化图形工具Qt Designer&#xff0c;文件名为designer.exe。如果在电脑上找不到&#xff0c;可以用如下命令进行安装&#xff1a; pip install PyQt5-tools 安装完毕后&#xff0c;可在如下目录找到此工具软件&#xff1a; %LOCALAPPDATA%\Programs\Python\…

2024人工智能“百模大战“,竞争格局分析

中国“百模大战”竞争格局分析 大模型是一个重资源禀赋和高进入门槛的赛道&#xff0c;“百模大战”是一场重投入和高消耗的持久战役。“百模大战”的上半场是资源和技术的碰撞&#xff0c;入局企业需要长久的资源支持获得高密度的人才、高质量的数据和大规模的算力&#xff0c…

Vue.js课后练习(登录注册和大小比较)

第一题 请编写登录页面和注册页面&#xff0c;通过动态组件实现动态切换页面中显示的组件&#xff0c;效果如图1和图2所示。 图1 登录页面 图2 注册页面 代码&#xff1a; my.vue代码: <template>登录 </template><script setup> </script><st…