`

快速排序及其简单优化

阅读更多

       快速排序是我们大一进入学校就会的东西,但我发现自己到了大学之后学东西非常 生硬,都是被别人灌输的,缺少了自己思考的过程,这几天被左神一语惊醒,我们学习算法应该是一个思考与探索的过程,不是简单的把这道题AC了就完事了,那我们大学之前那么辛苦可不是为了来大学玩的,所以以后要学会思考和学会探索;

       首先今天我们来讲的是快速排序,这里用三种方法来写快排的;

 ①设定一个标志,两个 哨兵分别从两端开始行走的方法,主代码如下:

public static void quickSort(int[] arr,int l,int r){

        if ( l < r ){
            //随机出标志数
            swap1(arr, l + (int) (Math.random() * (r - l + 1)), r);
            int q = partition(arr ,l , r);
            quickSort(arr,l,q-1);
            quickSort(arr,q+1,r);
        }
    }

public static int partition(int[] arr,int l,int r){
        int p = arr[l];//设置标志位置
        int i = l;//左哨兵
        int j = r;//右哨兵
        while (i < j){
            while (arr[j] >= p && i < j){
                j--;
            }
            if (i<j){
                swap1(arr,i,j);
            }
            while (arr[i] <= p && i < j){
                i++;
            }
            if (i<j){
                swap1(arr,i,j);
            }
        }
        return i;
    }

 ②把最右边的设置 为标志位,一个哨兵 从最左侧依次进行比较,把 数组 分为两个区,代码 如下:

public static void quickSort2(int[] arr,int l,int r){

        if ( l < r ){
            //随机产生标志位
            swap1(arr, l + (int) (Math.random() * (r - l + 1)), r);
            int q = partition2(arr,l,r);
            quickSort(arr,l,q-1);
            quickSort(arr,q+1,r);
        }
    }

public static int partition2(int[] arr,int l,int r){
        int i = l-1;
        int j = r;
        while (l < j){
            //每次把最右边的设置为标志位,这样减少了额外空间
            if (arr[l]<=arr[r]){
                i++;
                swap1(arr,i,l);
                l++;
            }else{
                j--;
                swap1(arr,j,l);
            }
        }
        swap1(arr,j,r);
        return i+1;
    }

 ③把数组分为三部分,大于区,小于区和等于区,这样会减少比较的次数,代码如下:

public static void quickSort1(int[] arr,int l,int r){

        if ( l < r ){
            swap1(arr, l + (int) (Math.random() * (r - l + 1)), r);
            int[] q = partition1(arr,l,r);
            quickSort(arr,l,q[0]-1);
            quickSort(arr,q[0]+1,r);
        }
    }

 //划分数组的优化算法,把一个数组分为三个区,大于区,小于区和等于区
    public static int[] partition1(int[] arr,int l,int  r){
        int i = l-1;
        int j = r;
        while (l < j){
            //每次把最右边的设置为哨兵,这样减少了额外空间
            if (arr[l]<arr[r]){
                swap1(arr,++i,l++);
            }else if (arr[l]>arr[r]){
                swap1(arr,--j,l);
            }else {
                l++;
            }
        }
        swap1(arr,j,r);
        return new int[] {i+1,j};
    }

 完整代码如下:

package study.tao.sort;

import java.util.Arrays;

/**
 * Created by Taoyongpan on 2017/11/13.
 * 快速排序及其优化,我们一般快排的时候会把一个数组 分为两个区
 * 大于等于和小于两个区,现在我们要做的是讲一个数组分为三个区,大于,等于和小于三个区
 * 这样做的好处是每次把相等的数放在中间位置,这样会减少比较次数
 */
public class QuickSort {

    //随机产生一个数组 大小为maxSize,最大值为maxValue的数组
    public static int[] generateRandomArray(int maxSize,int maxValue){
        if (maxSize<=0){
            return null;
        }
        int[] arr = new int[(int)((maxSize+1)*Math.random())];

        for (int i = 0 ; i < arr.length ; i++){
            arr[i] = (int) ((maxValue+1)*Math.random());
        }
        return arr;
    }

    //数组的输出函数
    public static void printArray(int[] arr){
        if (arr==null){
            return;
        }
        for (int j = 0 ; j < arr.length ; j++){
            System.out.print(arr[j]+" ");
        }
        System.out.println();
    }

    //复制函数
    public static int[] copyArray(int[] arr){
        int[] res = new int[arr.length];
        if (arr == null){
            return null;
        }
        for (int i = 0 ; i < arr.length ; i++){
            res[i] = arr[i];
        }
        return res;
    }

    //交换函数
    //位运算进行交换
    public static void swap(int[] arr,int i,int j){
        arr[i] = arr[i]^arr[j];
        arr[j] = arr[i]^arr[j];
        arr[i] = arr[i]^arr[j];
    }
    //需要额外空间的交换函数
    public static void swap1(int[] arr,int i,int j){
        int temp;
        temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
    //系统的比较函数
    public static void arraySort(int[] arr){
        Arrays.sort(arr);
    }

    //比较自己写的排序函数和系统的排序函数结果是否相等
    public static boolean isEqual(int[] arr1,int[] arr2){
        if ((arr1 == null && arr2 !=null)||(arr1 !=null && arr2 ==null)||( arr1 == null && arr2 == null)){
            return false;
        }
        if (arr1.length != arr2.length){
            return false;
        }
        for (int i = 0 ; i <arr1.length;i++){
            if (arr1[i] != arr2[i]){
                return false;
            }
        }
        return true;
    }
    //快速排序
    public static void quickSort(int[] arr,int l,int r){

        if ( l < r ){
            swap1(arr, l + (int) (Math.random() * (r - l + 1)), r);
            int q = partition(arr ,l , r);
            quickSort(arr,l,q-1);
            quickSort(arr,q+1,r);
        }
    }
    public static void quickSort1(int[] arr,int l,int r){

        if ( l < r ){
            swap1(arr, l + (int) (Math.random() * (r - l + 1)), r);
            int[] q = partition1(arr,l,r);
            quickSort(arr,l,q[0]-1);
            quickSort(arr,q[0]+1,r);
        }
    }
    public static void quickSort2(int[] arr,int l,int r){

        if ( l < r ){
            swap1(arr, l + (int) (Math.random() * (r - l + 1)), r);
            int q = partition2(arr,l,r);
            quickSort(arr,l,q-1);
            quickSort(arr,q+1,r);
        }
    }
    //定位函数
    //划分数组,用两个哨兵的方法
    public static int partition(int[] arr,int l,int r){
        int p = arr[l];//设置哨兵位置
        int i = l;
        int j = r;
        while (i < j){
            while (arr[j] >= p && i < j){
                j--;
            }
            if (i<j){
                swap1(arr,i,j);
            }
            while (arr[i] <= p && i < j){
                i++;
            }
            if (i<j){
                swap1(arr,i,j);
            }
        }
        return i;
    }
    //划分数组的优化算法,把一个数组分为三个区,大于区,小于区和等于区
    public static int[] partition1(int[] arr,int l,int  r){
        int i = l-1;
        int j = r;
        while (l < j){
            //每次把最右边的设置为哨兵,这样减少了额外空间
            if (arr[l]<arr[r]){
                swap1(arr,++i,l++);
            }else if (arr[l]>arr[r]){
                swap1(arr,--j,l);
            }else {
                l++;
            }
        }
        swap1(arr,j,r);
        return new int[] {i+1,j};
    }
    //划分数组的一级优化
    public static int partition2(int[] arr,int l,int r){
        int i = l-1;
        int j = r;
        while (l < j){
            //每次把最右边的设置为哨兵,这样减少了额外空间
            if (arr[l]<=arr[r]){
                i++;
                swap1(arr,i,l);
                l++;
            }else{
                j--;
                swap1(arr,j,l);
            }
        }
        swap1(arr,j,r);
        return i+1;
    }
    //主函数
    public static void main(String[] args){

        int maxSize = 100;
        int maxValue = 100;
        int maxTime = 3;
        boolean flag = true;
        int[] arr1 = generateRandomArray(maxSize,maxValue);//随机生成数组
        int[] arr2 = copyArray(arr1);//把数组1中的值复制到arr2中

        quickSort(arr1,0,arr1.length-1);
        arraySort(arr2);

        quickSort1(arr1,0,arr1.length-1);
        arraySort(arr2);

        quickSort2(arr1,0,arr1.length-1);
        arraySort(arr2);
        System.out.println(isEqual(arr1,arr2)?"succeed":"failed");
        printArray(arr1);
    }
}

 

分享到:
评论

相关推荐

    algorithm-java:基础算法Java版本 --持续更更新中

    快速排序 双基准快速排序 三路快速排序 堆排序 索引堆排序(堆排序拓展) 说明:从多角度进行测试及包括数据重复率,数据有序性等对单一角度或者多角度提出算法的优化策略 搜索算法 二分搜索树 二分搜索法及其变体 ...

    IOI国家集训队论文集1999-2019

    侯启明 -《信息论在信息学竞赛中的简单应用》 姜尚仆 -《模线性方程的应用——用数论方法解决整数问题》 金 恺 -《探寻深度优先搜索中的优化技巧——从正方形剖分问题谈起》 雷环中 -《结果提交类问题》 林希德 ...

    Python 在数据分析和可视化方面拥有强大的功能,它提供了许多库和工具,使得数据分析和数据可视化过程变得更加简单和高效 以下是

    SciPy 包含的模块有最优化、线性代数、积分、插值、特殊函数、快速傅里叶变换、信号处理、图像处理、常微分方程求解和其他科学与工程中常用的计算。 StatsModels: 提供了统计模型和统计检验的丰富集合,以及用于...

    并行计算导论(原书第2版).[美]Ananth Grama(带详细书签).pdf

    9.3 冒泡排序及其变体 9.3.1 奇偶转换 9.3.2 希尔排序 9.4 快速排序 9.4.1 并行快速排序 9.4.2 用于CRCWPRAM的并行形式 9.4.3 用于实际体系结构的并行形式 9.4.4 主元选择 9.5 桶和样本排序 9.6 其他排序...

    收获不知Oracle

    3.2.7.5 临时表空间组及其妙用114 3.3 课程结束你给程序安上了翅膀 117 3.3.1 过度扩展与性能 117 3.3.2 PCTFREE与性能120 3.3.3 行迁移与优化 123 3.3.4 块的大小与应用 124 第4章祝贺,表的设计成就英雄 131 4.1 ...

    solr 企业搜索引擎教程

    定制 Solr 索引的实现方法很简单,用 POST 方法向 Solr 服务器发送一 个描述所有 Field 及其内容的 XML 文档就可以了。定制搜索的时候只需要发送 HTTP GET 请求 即可,然后对 Solr 返回的信息进行重新布局,以产生利于...

    MYSQL网络数据库PDF学习资源

    第3章 MySQL SQL 语法及其用法 99 3.1 MySQL 中的SQL特征 99 3.2 MySQL 的命名规则 100 3.2.1 引用数据库的成分 100 3.2.2 SQL语句中的大小写规则 101 3.3 创建、删除和选择数据库 101 3.4 创建、删除、索引和更改表...

    mysql网络数据库指南(中文版) part1

    13.1.5 快速运行myisamchk和 isamchk 332 13.2 安排预防性的维护 333 13.2.1 用cron定期检查表 334 13.2.2 在系统启动期间检查表 335 第四部分 附 录 附录A 获得和安装软件 337 附录B 列类型参考 349 附录C ...

    asp.net知识库

    ASP.NET2.0 快速入门 ----默认中的主题外观 数据库开发 ADO.NET 通过DataTable获得表的主键 ADO.NET 2.0 操作实例 ADO.NET 2.0 大批量数据操作和多个动态的结果集 ADO.NET 2.0 异步处理 在ASP.NET中使用WINDOWS验证...

    阐述大型数据库系统安全风险及策略.docx

    阐述大型数据库系统安全风险及策略 1 数据库及其安全问题概述 数据库是存储在一起的相关结构化数据的集合,这些相关数据是无损害和不赘余的。它产生于距今50年前,随着信息技术和市场的发展,特别是20世纪90年代以后...

    数据结构、算法与应用:C++语言描述(原书第2版)第二部分

    18.2.3 快速排序 18.2.4 选择 18.2.5 相距最近的点对 18.3 解递归方程 18.4 复杂度的下限 18.4.1 最小最大问题的下限 18.4.2 排序算法的下限 第19章 动态规划 19.1 算法思想 19.2 应用 19.2.1 0/1背包问题 19.2.2 ...

    leetcode超时用例数-training:训练

    是:快速、积极、透明、基于事实、有条理和明确表达(防止隐藏的假设和卡住) 如果卡住了:保持冷静,检查假设,尝试更多例子,简化,询问,避免沉默或填补它 算法设计 通过示例消除歧义/澄清( :check_mark_button:...

    Oracle SQL高级编程(资深Oracle专家力作,OakTable团队推荐)--随书源代码

    Karen Morton及其团队在本书中提供了专业的方案:先掌握语言特性,再学习Oracle为提升语言效率而加入的支持特性,进而将两者综合考虑并在工作中加以应用。作者通过总结各自多年的软件开发和教学培训经验,与大家...

    OpenSceneGraph三维渲染引擎设计与实践

    12.2.3 渲染树的优化排序 338 12.2.4 范例:广告牌森林 339 12.3 多种线程模型的讨论与实现 341 12.3.1 渲染器与场景视图 341 12.3.2 单线程模型 347 12.3.3 多设备裁减/绘制模型 348 12.3.4 多设备绘制模型 ...

    C++网络爬虫项目

    引擎简单界面背后的技术原理其实对每一个希望在互联网行业有所建树的信息 技术人员都很重要。 1.1. 搜索引擎 作为互联网应用中最具技术含量的应用之一,优秀的搜索引擎需要复杂的架构 和算法,以此来支撑对海量数据...

    木翼下载系统(MYDOWN) 4.0

    功能强大,简单易用,生成静态页面,支持Tag, 支持关键词搜索记录,支持可自定义扩展字段, 及其内容设定, 全面满足下载型网站的需求。 木翼下载系统(MYDOWN) 4.0 修正了几个影响正常使用的bug:2011-06-30 1.修正...

    ASP.NET4高级程序设计第4版 带目录PDF 分卷压缩包 part1

    手动优化了PDF的书签,书签可折叠,书签链接以目录方式保存,多达1000多页,每页都做了书签定位,手都累酸啦。 ============================== 因权限只能到60MB,分卷压缩了,共3个压缩包,需下载完3个一起解压, ...

Global site tag (gtag.js) - Google Analytics