快速排序

快速排序及优化方案 文章目录快速排序及其优化方案1. 快速排序的流程2. 快速排序的实现时间复杂度计算3. 快速排序优化随机获取基准值进行优化3.2二路快速排序原理:思想:4. 总结 快速排序及其优化方案 1. 快速排序的流程 首先设定一个分界值,通过该分界值将数组分成左右两部分。 将大于分界值的数据集中到数组右边,小于分界值的数据集中到数组的左边,而等于分分界值的部分放在相对中间的部分。此时,左边部分中各元素都小于分界值,而右边部分中各元素都大于分界值,相对中间的部分的的数据等于分界值。 然后,左边和右边的数据可以独立排序 阅读详情

快速排序的基本思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。

算法描述

快速排序使用分治法来把一个串(list)分为两个子串(sub-lists)。具体算法描述如下:

  • 从数列中挑出一个元素,称为 “基准”(pivot);
  • 重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作;
  • 递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

Partition过程:

给定一个数组arr,和一个整数num。请把小于等于num的数放在数组的左边,大于num的数放在数组的右边。

要求额外空间复杂度O(1),时间复杂度O(N)

这里的num是数组最右边的数字

    public int partition(int[] arr, int left, int right) {
        int num = arr[right];
        int begin = left;
        int end = right;
        while (begin < end) {
            while (begin < end && arr[begin] <= num) {
                begin++;
            }
            while (begin < end && arr[end] >= num) {
                end--;
            }
            swap(arr, begin, end);
        }
        swap(arr, begin, right);
        return begin;
    }

但是如果很多相等的数字,这种方法就不是很好

下面这个方式,是将等于num的数字放在中间,小于num的放在左边,大于Num的放在右边

   // arr[L...R] 玩荷兰国旗问题的划分,以arr[R]做划分值
    //  <arr[R]  ==arr[R]  > arr[R]
    public int[] netherlandsFlag(int[] arr, int left, int right) {
        if (left > right) {
            return new int[]{-1, -1};
        }
        if (left == right) {
            return  new int[]{left, right};
        }
        int less = left - 1;
        int more = right;
        int index = left;
        while (index < more) {
            if (arr[index] == arr[right]) {
                index++;
            } else if (arr[index] < arr[right]) {
                swap(arr, index++, ++less);
            } else {
                swap(arr, index, --more);
            }

        }
        swap(arr, more, right);
        return new int[]{less + 1, more};
    }

快排1.0版本:

package com.zy.base.class003;

import java.util.Arrays;

public class Code03_PartitionAndQuickSort {
    public static void main(String[] args) {
        int[] arr = {3, 1, 3, 2, 10, 8, 9, 6, 8, 6};
        new Code03_PartitionAndQuickSort().quickSort1(arr);
        System.out.println(Arrays.toString(arr));
    }

    public int partition(int[] arr, int left, int right) {
        int num = arr[right];
        int begin = left;
        int end = right;
        while (begin < end) {
            while (begin < end && arr[begin] <= num) {
                begin++;
            }
            while (begin < end && arr[end] >= num) {
                end--;
            }
            swap(arr, begin, end);
        }
        swap(arr, begin, right);
        return begin;
    }

    private void swap(int[] arr, int left, int right) {
        int tmp = arr[left];
        arr[left] =arr[right];
        arr[right] = tmp;
    }

    // 快排递归版本
    public void quickSort1(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        process1(arr, 0, arr.length - 1);
    }

    private void process1(int[] arr, int left, int right) {
        if (left >= right) {
            return;
        }
        int partition = partition(arr, left, right);
        process1(arr, left, partition - 1);
        process1(arr, partition + 1, right);
    }
}

快速排序2.0版本

package com.zy.base.class003;

import java.util.Arrays;

public class Code03_PartitionAndQuickSort {
    public static void main(String[] args) {
        int[] arr = {3, 1, 3, 2, 10, 8, 9, 6, 8, 6};
//        int partition = new Code03_PartitionAndQuickSort().partition(arr, 0, arr.length - 1);
//        System.out.println(partition);
//        new Code03_PartitionAndQuickSort().netherlandsFlag(arr, 0, arr.length - 1);
        new Code03_PartitionAndQuickSort().quickSort2(arr);
        System.out.println(Arrays.toString(arr));

    }


    // arr[L...R] 玩荷兰国旗问题的划分,以arr[R]做划分值
    //  <arr[R]  ==arr[R]  > arr[R]
    public int[] netherlandsFlag(int[] arr, int left, int right) {
        if (left > right) {
            return new int[]{-1, -1};
        }
        if (left == right) {
            return  new int[]{left, right};
        }
        int less = left - 1;
        int more = right;
        int index = left;
        while (index < more) {
            if (arr[index] == arr[right]) {
                index++;
            } else if (arr[index] < arr[right]) {
                swap(arr, index++, ++less);
            } else {
                swap(arr, index, --more);
            }

        }
        swap(arr, more, right);
        return new int[]{less + 1, more};
    }

    private void swap(int[] arr, int left, int right) {
        int tmp = arr[left];
        arr[left] =arr[right];
        arr[right] = tmp;
    }



    // 快排递归版本
    public void quickSort2(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        process2(arr, 0, arr.length - 1);
    }

    private void process2(int[] arr, int left, int right) {
        if (left >= right) {
            return;
        }
        int[] ints = netherlandsFlag(arr, left, right);
        process2(arr, left, ints[0] - 1);
        process2(arr, ints[1] + 1, right);

    }
}

快速排序3.0

package com.zy.base.class003;

import java.util.Arrays;

public class Code03_PartitionAndQuickSort {
    public static void main(String[] args) {
        int[] arr = {3, 1, 3, 2, 10, 8, 9, 6, 8, 6};
//        int partition = new Code03_PartitionAndQuickSort().partition(arr, 0, arr.length - 1);
//        System.out.println(partition);
//        new Code03_PartitionAndQuickSort().netherlandsFlag(arr, 0, arr.length - 1);
        new Code03_PartitionAndQuickSort().quickSort3(arr);
        System.out.println(Arrays.toString(arr));


    }


    // arr[L...R] 玩荷兰国旗问题的划分,以arr[R]做划分值
    //  <arr[R]  ==arr[R]  > arr[R]
    public int[] netherlandsFlag(int[] arr, int left, int right) {
        if (left > right) {
            return new int[]{-1, -1};
        }
        if (left == right) {
            return  new int[]{left, right};
        }
        int less = left - 1;
        int more = right;
        int index = left;
        while (index < more) {
            if (arr[index] == arr[right]) {
                index++;
            } else if (arr[index] < arr[right]) {
                swap(arr, index++, ++less);
            } else {
                swap(arr, index, --more);
            }

        }
        swap(arr, more, right);
        return new int[]{less + 1, more};
    }

    private void swap(int[] arr, int left, int right) {
        int tmp = arr[left];
        arr[left] =arr[right];
        arr[right] = tmp;
    }


    public void quickSort3(int[] arr) {
        if (arr == null || arr.length < 2) {
            return;
        }
        process3(arr, 0, arr.length - 1);
    }

    private void process3(int[] arr, int start, int end) {
        if (start >= end) {
            return;
        }
        swap(arr, start + (int) Math.random() * (end - start + 1), end);
        int[] ints = netherlandsFlag(arr, start, end);
        process3(arr, start, ints[0] - 1);
        process3(arr, ints[0] + 1, end);
    }
}

 

 

 

 

基于MIPS汇编语言的快速排序 这是我翻译的MIPS汇编语言的快速排序的代码,欢迎大家学习交流 立即下载

相关推荐

C# 读取图片和扫描PDF中的文本

本博客将探讨如何使用C#和OCR库实现从图片和扫描的 PDF 中提取文本。Spire.OCR for .NET 是一个OCR文字识别库,专为在 .NET 应用程序中识别图片的文本而设计。首先,使用 Spire.PDF 将扫描的 PDF 转换为图片,然后利用 Spire.OCR 从这些图片中提取文本。由于该OCR库并不支持直接处理PDF,因此要从扫描的 PDF 中提取文本,我们首先需要将 PDF 文档转换为图片。转换完成后,再利用 Spire.OCR 从生成的图片中提取文本。方法来识别图片中的文本。

nuclear2011的博客 5401

从partition到Quicksort

本文主要讨论quicksort和寻找第k大元素的两个相关问题。 力扣连接https://leetcode-cn.com/problems/sort-an-array/【排序算法精华3】快速排序 (上)_哔哩哔哩_bilibili"五点七边-算法学习" QQ交流群:539835344快速排序(英语:Quicksort),简称快排,是一种排序算法,最早由东尼·霍尔提出。正如它的名字所暗示的那样,快速排序的最大优点在于它的速度非常快。在实现的比较好的时候,快速排序往往比归并排序、堆排序等优秀的排序算法更快...

m0_47096428的博客 453

STM32 WinUSB免驱实现:从DFU模式到高速通信的实战指南

本文详细介绍了STM32 WinUSB免驱实现方案,从DFU模式到高速通信的完整实战指南。通过修改设备描述符、添加BOS描述符和实现WCID描述符集,开发者可以轻松实现即插即用的USB设备,无需额外安装驱动。文章还提供了性能优化技巧和实际应用案例,帮助开发者快速部署高效稳定的USB通信方案。

weixin_29171087的博客 422

排序算法之快速排序

快速排序(英语:Quicksort),又称划分交换排序(partition-exchange sort),通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。 步骤为: 1. 从数列中挑出一个元素,称为"基准"(pivot), 2. 重新排序数列

jianglinwei_Xian的博客 377

Wafer的T7 Code是什么,怎么来的

在半导体Cim系统中,waferstart 业务需要支持 Sorter 读取 Wafer 的 T7 Code,与 MES 的 Wafer ID 进行绑定,以便向 前追溯 Wafer 历史,那么问题来了,T7code 是什么Wafer的T7 Code是一种,用于标识双面抛光的晶圆。这种标记采用二维矩阵代码符号,适用于各种尺寸的晶圆,不仅限于450mm无缺口晶圆7。T7 Code是衬底来料背面通常会有的供应商刻的追溯ID,这是一串数字和字母组成的流水码。

阿拉伯梳子的专栏 7925

安路科技FPSoC开发实战:从芯片特性到边缘计算应用

本文深入解析安路科技FPSoC芯片在边缘计算领域的开发实战,重点介绍SALDRAGON系列芯片的异构计算架构优势,包括RISC-V/ARM处理器与FPGA的协同工作。通过工业控制和智能视觉应用案例,展示硬件加速实现与低功耗设计技巧,帮助开发者高效利用FPSoC进行边缘计算应用开发。

weixin_29248611的博客 375

数据结构与算法(一):排序算法之 - 快速排序(详细步骤图解,附代码)

快速排序 引子:Partition 过程 给定一个数组arr,和一个整数num。请把小于等于num的数放在数组的左边,大于num的数放在数组的右边。 要求额外空间复杂度O(1),时间复杂度O(N) 思路 维护一个 小于区,i 从第一个数开始: 只要 i 小于 num,就把 i 与 *小于区右侧的第一个数 *交换,并将小于区向右扩大一个数 如果 i 大于等于 num,将 i++ 这样做的原理依据是: 在 i 的左侧,都是看过的数,并且每一次比较,都把比 num 小的数发送到小于区。而 i 右侧是没看过的数

寒泉 7万+

ROS2仿真抓取分拣案例,使用myCobot 280机械臂结合ROS2系统搭建机械分拣站

本案例展示了如何利用myCobot 280 urdf模型构建一个对象分类站,并在ROS2 jazzy中完成运动规划。

m0_71627844的博客 2125

三种快速排序以及快速排序的优化

1、快速排序的基本思想:    快速排序使用分治的思想,通过一趟排序将待排序列分割成两部分,其中一部分记录的关键字均比另一部分记录的关键字小。之后分别对这两部分记录继续进行排序,以达到整个序列有序的目的。 2、快速排序的三个步骤: (1)选择基准:在待排序列中,按照某种方式挑出一个元素,作为 "基准"(pivot) (2)分割操作:以该基准在序列中的实际位置,把序列分成两个子序列。此时,在

思考,思考,再思考~ 5万+

高分辨率航拍图像的目标检测切图优化策略

本文深入探讨了高分辨率航拍图像目标检测中的切图优化策略。针对大尺寸图像直接缩放导致小目标信息丢失的问题,文章详细阐述了基于重叠切割的核心方法,包括如何根据目标尺寸确定切图尺寸与重叠率,并提供了从切图到坐标还原的完整代码实现与避坑指南,有效提升检测精度与效率。

xk7n92h3p5m的博客 1113

深度学习PyTorch代码模板——模型训练框架、数据处理、绘图…

个人用深度学习代码模板:模型训练框架、数据处理、绘图等。待补充。

https://www.hyperplasma.top 1908

经典快速排序与随机快速排序

文章目录一、经典快速排序(一)、经典快速排序的实现理论(二)、经典快速排序的代码实现(Java)(三)、经典快速排序的时间复杂度二、随机快速排序(一)随机快速排序的实现理论(二)随机快速排序的代码实现(Java)(三)、随机快速排序的时间复杂度 一、经典快速排序 (一)、经典快速排序的实现理论 经典快速排序是用数组的最后一个数(这里记为 x )进行划分。也就是 &amp;lt;x、=x、&amp;gt;x。 有...

liyanan的博客 3038

【4. BSP开发指南 - [4.6. 安全启动使用说明]】

【4. BSP开发指南 - [4.6. 安全启动使用说明]】

Sugar_wolf的博客 275

双路快速排序

双路快速排序算法是随机化快速排序的改进版本,partition 过程使用两个索引值(i、j)用来遍历数组,将v的元素放在索引j所指向位置的右边,v代表标定值。

fangfan9的博客 2376

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

图解快速排序及双路三路快速排序

前言 之前我们介绍了交换类排序中的冒泡排序,这次我们介绍另一种交换类排序叫做快速排序。快速排序的优点是原地排序,不占用额外空间,时间复杂度是O(nlogn)。 当然,对于快速排序来说,它也是有缺点的,它对于含有大量重复元素的数组排序效率是非常低的,时间复杂度会降为O(n^2)。此时需要使用改进的快速排序—双路快速排序,在双路快速排序的基础上,我们又进一步优化得到了三路快速排序。 快速排序 快速排...

子居的博客 1191

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

什么是快速排序?

文章目录快速排序快速排序简介:基本思想原理快速排序法示意图排序演示Java代码 快速排序 快速排序简介: 快速排序是对冒泡排序的一种改进。 基本思想 通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都小于或者等于另外一部分的所有数据,然后再按照此方法对这两部分数据分别进行快速排序,整个排序的过程可以递归进行,以此达到整个数据变成有序序列。 原理 设要排序的数组是A[0]……A[N-1],首先任意选取一个数据(通常选 用数组的第一个数)作为关键数据,然后将所有比它小的数都放到它左边,所

热爱编程的菜鸟 5600

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

快速排序——详解

快速排序(英语:Quicksort),又称分区交换排序(英语:partition-exchange sort),简称「快排」,是一种被广泛运用的排序算法。三路快速排序(英语:3-way Radix Quicksort)是快速排序和基数排序的混合。它的算法思想基于荷兰国旗问题的解法。内省排序(英语:Introsort 或 Introspective sort)4是快速排序和堆排序的结合,由 David Musser 于 1997 年发明。内省排序其实是对快速排序的一种优化,保证了最差时间复杂度为。

w_w_wwwww的博客 1374

手写快速排序

快速排序简介快速排序是一种很不错的排序算法,算法复杂度为n*logn。快排使用了分而治之的思想,每次排序是都找到一个基准(我们学习时经常使用第一个作为基准),然后把小于基准的元素放到基准元素的左边,大于基准的元素放到基准元素的右边,这样一次排序下来,基准元素左边都是小于(等于)基准的数,基准右边的元素都是大于(等于)基准的元素了。快速排序关键点就是找到这样一个基准并将其放到恰到的位置。算法思路定义一

God Liao On The Way 1万+

[算法]快速排序与随机快速排序

与归并排序一样,快速排序也运用了分治策略,而随机快速排序是对快速排序的一种优化。

hula_hula_的博客 1635

分治之快速排序以及快速排序为何最快

算法思想 数组排序任务可以如下完成: 1)设k=a[0],将k挪到适当位置,使得比k小的元素都在k的左边,比k大的元素都在k的右边,和k相等的,不关心在k左右出现均可(O(n)时间完成) 2)把k左边的部分快速排序 3)把k右边的部分快速排序 (假设运气比较好,每次基准元素被移动到中间,这样的话时间复杂度为O(nlogn)) 如何在O(n)的时间内将数组分成两半,一般在小于基准值,一般大于基准值? 程序代码 #include<iostream> using namespace std; int

Java硬件工程师的博客 3190

【快速排序】快速排序/第k个数

acwing算法学习笔记 -----快速排序

青竹雾色间.的博客 1998
上一篇: 归并排序
下一篇: 设计模式之策略模式
给自己加加油
博客等级 码龄8年 302粉丝 110原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值