快排的优化方法(优化营商环境方案)

聚集相同元素排序是快速排序的一种优化方案,它的思路是在经过一次找基准之后把数据中与基准相同的数据聚集到基准左右,这样就可以少进行几次递归找基准的过程,从而提高了运行效率。看以下程序:importjava.util.Arrays;publicclassFocusAlikeQuickSort{/**找基准的方法,与前文相同*/publicstatic…

大家好,又见面了,我是你们的朋友全栈君。

先来复习下找基准的方法:

public static int partion(int[] arr, int start, int end) { int tmp = arr[start];

        while (start < end) { while (arr[end] >= tmp && start < end) { --end;
            }

            if (start >= end) { break;
            }else {
                arr[start] = arr[end];
            }

            while (start < end && arr[start] <= tmp) { ++start;
            }

            if (start >= end) { break;
            }else {
                arr[end] = arr[start];
            }
        }

        arr[start] = tmp;
        return start;
    }

后面所有的优化程序都采用该方法来找基准。



一、聚集相同元素法

聚集相同元素排序是快速排序的一种优化方案,它的思路是在经过一次找基准之后把数据中与基准相同的数据聚集到基准左右,这样就可以少进行几次递归找基准的过程,从而提高了运行效率。
看以下程序:

public class FocusAlikeQuickSort { 
   

    /** 聚集相同元素 */
    public static int[] focusNum(int[] arr, int start, int end, int par) {
        int parLeft = par - 1;
        int parRight = par + 1;
        // 寻找并聚集基准左边与基准相同的元素
        for (int i = par - 1; i >= start; i--) {
            if (arr[i] == arr[par]) {
                if (i != parLeft) {
                    // 依次遍历比较,相同就交换位置
                    int tmp = arr[parLeft];
                    arr[parLeft] = arr[i];
                    arr[i] = tmp;
                    parLeft--;  
                }else {
                    parLeft--;
                }
            }
        }
        // 寻找并聚集基准右边与基准相同的元素
        for (int j = par + 1; j <= end; j++) {
            if (arr[j] == arr[par]) {
                if (j != parRight) {
                    // 依次遍历比较,相同就交换位置
                    int tmp = arr[parRight];
                    arr[parRight] = arr[j];
                    arr[j] = tmp;
                    parRight++;
                }else {
                    parRight++;
                }
            }
        }
        // 以数组的形式返回聚集相同元素之后的未有序数据的边界
        int[] array = new int[2];
        array[0] = parLeft;
        array[1] = parRight;
        return array;
    }

    public static void quickSort(int[] arr, int start, int end) {
        int par = partion(arr, start, end);
        // 聚集相同元素
        int[] array = focusNum(arr, start, end, par);
        int left = array[0];
        int right = array[1];

        if (par > start + 1) {
            quickSort (arr, start, left);
        }

        if (par < end - 1) {
            quickSort (arr, right, end);
        }
    }
}

运行过程是这样的:
这里写图片描述



二、随机取基准法

随机取基准法是快速排序的另一种优化方案,它是通过产生随机数的方式在数据中随机选取一个数据来进行找基准操作,次方法较快排在效率上有一定的提高。
看程序:

public class RandomQuickSort {
    public static void swap(int [] arr, int start, int end) {

        int tmp = arr[start];
        arr[start] = arr[end];
        arr[end] = tmp;
    }

    public static void quickSort(int[] arr, int start, int end) {
        // 产生在[start, end]之间的随机数
        Random rand = new Random();
        int randNum = rand.nextInt(end - start + 1) + start;
        // 将随机数交换到start位置
        swap(arr, start, randNum);

        int par = partion(arr, start, end);

        if (par > start + 1) {
            quickSort (arr, start, par - 1);
        }

        if (par < end - 1) {
            quickSort (arr, par + 1, end);
        }
    }
}


三、三分取基准法

此方法也是快速排序的一种优化方案,它的思路是比较数据中start,end以及两者中间位置的数据的大小,将这三个值中处于中间位置的值放到首位,再进行找基准操作,此方法较之快排在效率上也有一定的提高。
看程序:

public class ThirdPartitionQuickSort { 
   
    /** 交换方法 */
    public static void swap(int [] arr, int start, int end) {
        int tmp = arr[start];
        arr[start] = arr[end];
        arr[end] = tmp;
    }
    /** 比较结束后开始值,中间值和结尾值有序 */
    public static void SelectPivotMedianOfThree(int arr[], int low, int high){  
        int mid = low + ((high - low) >> 1);
        // 确定中间值小于结尾值
        if (arr[mid] > arr[high]) {  
            swap(arr, mid, high);  
        }  
        // 确定开始值小于结尾值
        if (arr[low] > arr[high]) {  
            swap(arr, low, high);  
        }  
        // 确定开始值大于中间值
        if (arr[mid] > arr[low]) {  
            swap(arr, mid, low);  
        }
    }  

    public static void quickSort(int[] arr, int start, int end) {
        // 三分确定首位
        SelectPivotMedianOfThree(arr, start, end);

        int par = partion(arr, start, end);

        if (par > start + 1) {
            quickSort (arr, start, par - 1);
        }

        if (par < end - 1) {
            quickSort (arr, par + 1, end);
        }
    }
}


以上三种方式以及上文末尾提到的优化方法往往结合使用,这样优化后的效率才能有明显的提高。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/128005.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 常见贴片电容封装尺寸

    常见贴片电容封装尺寸贴片电容封装尺寸 毫米 英寸 封装 L 长度公制 毫米 英制 英寸 W 宽度公制 毫米 英制 英寸 t 端点公制 毫米 英制 英寸 02010 60 0 03 0 024 0 001 0 30 0 03 0 011

    2026年1月15日
    1
  • T-SQL性能调整(一)–编译和重新编译

    T-SQL性能调整(一)–编译和重新编译

    2021年11月25日
    41
  • jmap的使用以及内存溢出分析

    jmap的使用以及内存溢出分析jmap 的使用以及内存溢出分析 jmap java 内存映像工具 jmap MemoryMapfor 命令用于生成堆转储快照 一般称为 heapdump 或 dump 文件 还有几种方式获取 dump 文件 使用 JVM 参数选项 XX HeapDumpOnOu 参数 可以让虚拟机在 OOM 异常出现之后自动生成 dump 文件 通过 XX HeapDumpPath path 设置 dump 文件路径 有时候 dump 文件比较大的时候可能无法自动导出 这时候就需要使用 jmap dump 手动导

    2025年12月6日
    4
  • 日期函数months_between的用法[通俗易懂]

    日期函数months_between的用法[通俗易懂]MONTHS_BETWEEN(date1,date2)用于计算date1和date2之间有几个月。如果date1在日历中比date2晚,那么MONTHS_BETWEEN()就返回一个正数。如果date1在日历中比date2早,那么MONTHS_BETWEEN()就返回一个负数。如果date1和date2日期一样,那么MONTHS_BET…

    2022年7月12日
    30
  • matlab学习五,二元函数绘图方法

    matlab学习五,二元函数绘图方法plot3()绘制空间曲线%plot3(x,y,z,S)x,y,z为坐标,S为线型%绘制三维螺旋线x=cos(t)y=sin(t)z=tt=0:0.1:10*pi;x=cos(t);y=sin(t);z=t;plot3(x,y,z,’-r’);xlabel(‘x’);ylabel(‘y’);zlabel(‘z’);title(‘三维螺旋线’);2.绘制空间曲面绘制空间曲面的步骤为:绘制平面网格,计算网格上的函数值,绘制网面首先是绘制平面网格[X,Y]=m.

    2025年9月29日
    5
  • 零基础学Java(2)数据类型与变量

    零基础学Java(2)数据类型与变量前言Java是一种强类型语言。这就意味着必须为每一个变量声明一种类型。在Java中,一共8种基本类型,其中有4种整型、2种浮点型、1种字符串类型char(用于表示Unicode编码的代码单元)和1种

    2022年8月7日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号