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

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


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

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 计算机视觉–光流法(optical flow)简介[通俗易懂]

    计算机视觉–光流法(optical flow)简介[通俗易懂]光流法理论背景1.什么是光流光流(opticalflow)是空间运动物体在观察成像平面上的像素运动的瞬时速度。光流法是利用图像序列中像素在时间域上的变化以及相邻帧之间的相关性来找到上一帧跟当前帧之间存在的对应关系,从而计算出相邻帧之间物体的运动信息的一种方法。通常将二维图像平面特定坐标点上的灰度瞬时变化率定义为光流矢量。一言以概之:所谓光流就是瞬时速率,在时间间隔很小(…

  • linux防火墙设置白名单_Linux永久关闭防火墙

    linux防火墙设置白名单_Linux永久关闭防火墙注:来自同事的笔记。如果防火墙开启,我们pingLinux服务器的IP会ping不通,所以我们要对防火墙进行设置(一般情况下只需执行1里边的命令就可以了):1、firewalld的基本使用启动防火墙:systemctlstartfirewalld查看防火墙状态:systemctlstatusfirewalld停止防火墙:systemctldisablefire…

  • mysql分页查询如何优化_mysql分页查询优化

    mysql分页查询如何优化_mysql分页查询优化测试实验1.直接用limitstart,count分页语句,也是我程序中用的方法:select*fromproductlimitstart,count当起始页较小时,查询没有性能问题,我们分别看下从10,100,1000,10000开始分页的执行时间(每页取20条),如下:select*fromproductlimit10,200.016秒sele…

  • JDK卸载与重装「建议收藏」

    JDK卸载与重装「建议收藏」JDK卸载与重装前言彻底卸载JDK这样新的jdk就安装完成了前言发现网上很多博文并没有完整的讲述如何卸载和重装jdk,自己在重装jdk的时候遇到很多问题,搜索很多博文,把内容整合起来,才解决问题,而且还有许多安装jdk,还要配置classpath环境变量,在jdk1.5版本之后已经不需要配置。本篇博文详细记录重装jdk的过程。彻底卸载JDK第一步:卸载原先的JDK(1)用控制面板卸载(2)安全类软件(360等)自带的软件卸载工具的功能卸载(3)直接删除jDK文件夹第二步:删除注册表

  • Charles抓包显示乱码解决方法

    Charles抓包显示乱码解决方法

  • PCL点云处理算法汇总(C++长期更新版)

    PCL点云处理算法汇总(C++长期更新版)PCL学习目录

发表回复

您的电子邮箱地址不会被公开。

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