对所有数据类型可通用的快速排序算法

2023-11-08

1.引子

快速排序算法可能是最优秀的排序算法了,此算法是1960年C.A.Hoare发明出来的,它被列为20世纪十大算法之一。快速排序也属于广义上的冒泡排序,这是简单冒泡排序法的优化升级。两者都是通过比较大小、交换元素来排序的,不过它增大了元素的比较和移动的跨度。这使得快速排序避免了一些额外的计算,进而实现更高的排序效率。

2.基本思路

从数组中取出一个元素作为基准值, 将较大的记录直接移动到基准值的后面,较小的元素移动到基准值的前面, 通过一趟排序将待排序的数组分割成了独立的两部分,再然后递归地对这两个组分别做排序。
组划分操作会事先选取一个随机元素作为基准值,并将交换是最前边。然后再比较其他元素,把小于基准值的元素向前交换到last索引位置,大于基准值的元素向后交换到i索引位置。从for循环开始的地方,从1至last的元素小于基准值,从last+1至i-1的元素大于等于基准值,而i至n-1的元素还未检查。接下来会递归检查i至n-1的元素,在所有元素划分完毕后,就交换索引0和last的元素,把基准值放回了原来的位置,这样就完成了所有元素的排序工作

  • 基准元素交换开始时
    基准元素交换开始时
  • 检查交换元素过程中
    检查交换元素过程中
  • 检查交换元素最后一步
    检查交换元素最后一步

3.实现代码

1)比较器接口

//泛型比较器接口,确定两元素的前后关系
public interface Cmp<T>
{
    /*
     * 如果x应该排在前,返回值为1; 
     * 如果x,y两者相等,返回值为0;
     * 如果y应该排在前,返回值为-1.
     */
    int copmare(T obj1, T obj2);
}

2)数组元素的比较器实现类

//实现比较器接口
final class IntegerCmp implements Cmp<Integer>
{
    @Override
    public int copmare(Integer x, Integer y)
    { 
        return x.compareTo(y);
    }
}

3) 快速排序工具类

import java.util.Random;

public final class SortDemo<T>
{
    
    private static Random rd = new Random();
    
    //array为待排序的数组名,left/right为需要排序的索引范围,cmp为数组元素的比较器对象
    public static <T> void sort(T[] array, int left, int right, Cmp<T> cmp)
    {
        //left等于right时表明完成了所有的排序,不需要再递归排序了,方法结束
        if (left >= right)
            return;
      
        int rdIndex=rand(left,right);
        //将数组最左边的元素与一随机索引rdIndex对应的元素互换,设置基准值
        swap(array,left, rdIndex);
        
        int last = left;
        //分隔成两部分
        for (int i = left + 1; i <= right; i++)
        {
            if (cmp.copmare(array[i], array[left]) < 0)
            {
                swap(array, ++last, i);
            }
        }
        //恢复原来的基准值
        swap(array, left, last);
        //对左侧部分递归排序
        sort(array, left, last - 1, cmp);
        //对右侧部分递归排序
        sort(array, last + 1, right, cmp);
        
    }
    
    public static <T> void sort(T[] array, Cmp<T> cmp)
    {
        sort(array, 0, array.length - 1, cmp);
    }
    
    //产生一个在left至right之间的一个随机数(不包括边界left、right)
    private static int rand(int left, int right)
    {
         return left + Math.abs(rd.nextInt() % (right - left + 1));
        
    }
    //互换索引位置i 、j的元素
    private static <T> void swap(T[] array, int i, int j)
    {
        T temp = array[j];
        array[j] = array[i];
        array[i] = temp;
    }
}

4.测试结果

  • 测试代码
 public static void main(String[] args)
    {
        Integer[] nums = new Integer[10000000];
        Cmp<Integer> cmp = new IntegerCmp();
        for (int endIndex = nums.length - 1, i = endIndex; i >= 0; i--)
        {
            nums[i] = endIndex - i;
        }
        
        Integer[] partNums = new Integer[50];
        System.arraycopy(nums, 1992, partNums, 0, partNums.length);
        System.out.println(Arrays.toString(partNums));
        
        long startTime = System.currentTimeMillis();
        SortDemo.sort(nums, cmp);
        long endTime = System.currentTimeMillis();
        
        System.arraycopy(nums, 100009, partNums, 0, partNums.length);
        System.out.println(Arrays.toString(partNums));
        
        System.out.println("对10000000个数字排序用时" + (endTime - startTime) + "毫秒");
    }
  • 控制台输出
    控制台信息
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

对所有数据类型可通用的快速排序算法 的相关文章

随机推荐

  • 继承。。。

    继承 上节回顾 static 静态的 作用 可以用来修饰成员变量 gt 静态变量 类变量 静态变量它是随着类的加载而加载 它被这个类的所有对象共享 普通成员变量 实例变量 它是随着对象的创建而产生 在不同的对象之间 是相互独立的 可以用来修
  • java中的IO整理

    写在前面 本文章基本覆盖了java IO的全部内容 文章以例子为主 因为讲解内容的java书很多了 我觉的学以致用才是真 代码是写出来的 不是看出来的 最后欢迎大家提出意见和建议 案例1 创建一个新文件 1 2 3 4 5 6
  • linux安装nginx+php

    在centos服务器下 mkdir docker cd docker mkdir nginx mkdir php mkdir www 2 拉取镜像 docker pull nginx docker pull php 7 4 fpm dock
  • CentOS 7 分区方案

    通常系统盘都会选择性能较好SSD 一般在500G左右 这里就以500G硬盘为例 以下为CentOS 自动分区方案 分区应该按照实际服务器用途而定 自动分区方案将 home 空间分配太多了 多数情况下并不适用 必须存在的分区 分区是必须存在的
  • 如何卸载、删除Anaconda?

    Anaconda这么好用 为啥要删呢 当然是我之前装得乱七八糟 导致现在心情不好 我要把它全部删掉 ok 开始 删除思路 首先利用anaconda clean清理包清理配置文件 然后直接用安装目录下的卸载程序卸载即可 一 anaconda
  • 算法分析基础

    问题 如何比较不同算法的性能 分析算法的运行时间 算法分析的原则 归纳基本操作 如 运算 赋值 比较 统一机器性能 假设基本操作代价均为1 统一机器性能后 算法运行时间依赖于问题输入规模与实例 相同输入规模 实例影响运行 最好情况 不常出现
  • spark 参数调优3-Shuffle Behavior

    spark参数调优系列 目录地址 https blog csdn net zyzzxycj article details 81011540 Shuffle Behavior spark reducer maxSizeInFlight 默认
  • JSP中使用element-ui

    首先需要下载element ui 可以直接在github下载即可 script 引入 这样就可以使用了 如 this message 已经上传过了 无需重复上传 注 vue里面直接使用 this即可 jsp里面想使用的可以试试了
  • 浏览器客户端生成唯一标识码

    created this getFinger methods getFinger const canvas document createElement canvas const ctx canvas getContext 2d const
  • 人工智能:深度学习算法及应用——简单理解CNN卷积神经网络并python实现(带源码)

    深度学习算法及应用 一 实验目的 二 实验要求 三 实验的硬件 软件平台 四 实验原理 1 1 深度学习概述 1 2 深度学习的常见结构 1 3 卷积神经网络 CNN 卷积 池化 全连接网络 1 4 卷积神经网络的大致结构 1 5 参数学习
  • 动态规划—分割回文串-ii 解析+代码

    分割回文串 ii 题目链接 分割回文串 ii 思路 分割字符串s 使得子串都是回文串 最后获得最小分割次数 那么我们可以不断把字符串缩短 判断子串是否可以被分割成回文串 并且最小分割次数 这就是子问题分割了 所以我们可以使用动态规划 状态
  • python3 发送邮件 send mail 使用 163 smtp服务器

    监控本地网络速度 通过api 请求速度 发现速度异常 发送报警邮件 usr bin env python3 coding UTF 8 import smtplib time from email mime text import MIMET
  • 深入理解equals和==的区别

    今天在群里面看到这个问题 equals和 的区别是什么 我有点迟钝 不就是如果是String类型的话equals比较的是内容 非字符串类型则比较的是内容吗 我想里面的考点也没有多少吧 然后我就回复了一个 equals本来就是为了比较内容出现
  • c++ STL中sort函数的三种使用方法

    复习一下 STL C 中的标准模板库 使用起来方便并且效率较高 sort函数有三种用法 一 对基本类型数组从小到大排序 sort 数组名 n1 数组名 n2 将数组中下标从n1到n2的元素进行从小到大排序 不包括n2 通过n1 n2 可以对
  • 已经有dll文件,报错:“缺少XXXXX.dll 无法继续执行代码。重新安装程序可能会解决此问题”解决方案

    解决方案 尝试了博客的很多方法 都建议直接复制dll到工程目录 觉得特别繁琐 而且会导致项目文件夹很大 从这篇文章得到启发 链接 项目 gt 属性 gt 调试 gt 环境 输入path 不要空格 你存储dll的目录 注意 不要有空格 例如我
  • MES相关名词解释

    SOA Service Oriented Architecture SOA 面向服务的体系结构AMR Advanced Manufacturing Research 先进制造研究机构CIM Computer Integrated Manuf
  • 【react】react全家桶介绍

    1 react基础 2 react router 路由库 3 pubsub 消息管理的库 4 redux 集中式状态管理的库 5 ant design UI库 react是用于构建用户界面的javascript库 1 发送请求获取数据 2
  • JAVA基础知识(五)

    5 4 构造方法 构造方法的主要作用就是为类中的属性初始化 类名称 对象名称 new 类名称 从格式中发现 在最后有一个类名称 的代码 在程序中只要是一看见有 就表示调用方法 那么这个方法实际上就是要表示调用构造方法 构造方法可视为一种特殊
  • 移动端如何浏览EXCEL、word、ppt、pdf等文件在线预览?

    1 简单的前端处理方式 a href 文档地址 a 或者JS window open 文档地址 新建窗口打开链接预览 window location href 文档地址 本页面内跳转链接实现预览 这种方式在不同浏览器上表现不一样 部份手机浏
  • 对所有数据类型可通用的快速排序算法

    1 引子 快速排序算法可能是最优秀的排序算法了 此算法是1960年C A Hoare发明出来的 它被列为20世纪十大算法之一 快速排序也属于广义上的冒泡排序 这是简单冒泡排序法的优化升级 两者都是通过比较大小 交换元素来排序的 不过它增大了