我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Arrays.sort(arr)代码逻辑是什么

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Arrays.sort(arr)代码逻辑是什么

本篇内容介绍了“Arrays.sort(arr)代码逻辑是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

首先看源码:

 public static void sort(int[] a) {        DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0);    }

它调用了DualPivotQuicksort的sort方法,乍一看以为是快排,这是很多网上的博主的说法,继续点开向下看(代码太长,没耐心看可以直接跳过该段代码QWQ):

 static void sort(int[] a, int left, int right,                     int[] work, int workBase, int workLen) {        // Use Quicksort on small arrays        if (right - left < QUICKSORT_THRESHOLD) {            sort(a, left, right, true);            return;        }                int[] run = new int[MAX_RUN_COUNT + 1];        int count = 0; run[0] = left;        // Check if the array is nearly sorted        for (int k = left; k < right; run[count] = k) {            if (a[k] < a[k + 1]) { // ascending                while (++k <= right && a[k - 1] <= a[k]);            } else if (a[k] > a[k + 1]) { // descending                while (++k <= right && a[k - 1] >= a[k]);                for (int lo = run[count] - 1, hi = k; ++lo < --hi; ) {                    int t = a[lo]; a[lo] = a[hi]; a[hi] = t;                }            } else { // equal                for (int m = MAX_RUN_LENGTH; ++k <= right && a[k - 1] == a[k]; ) {                    if (--m == 0) {                        sort(a, left, right, true);                        return;                    }                }            }                        if (++count == MAX_RUN_COUNT) {                sort(a, left, right, true);                return;            }        }        // Check special cases        // Implementation note: variable "right" is increased by 1.        if (run[count] == right++) { // The last run contains one element            run[++count] = right;        } else if (count == 1) { // The array is already sorted            return;        }        // Determine alternation base for merge        byte odd = 0;        for (int n = 1; (n <<= 1) < count; odd ^= 1);        // Use or create temporary array b for merging        int[] b;                 // temp array; alternates with a        int ao, bo;              // array offsets from 'left'        int blen = right - left; // space needed for b        if (work == null || workLen < blen || workBase + blen > work.length) {            work = new int[blen];            workBase = 0;        }        if (odd == 0) {            System.arraycopy(a, left, work, workBase, blen);            b = a;            bo = 0;            a = work;            ao = workBase - left;        } else {            b = work;            ao = 0;            bo = workBase - left;        }        // Merging        for (int last; count > 1; count = last) {            for (int k = (last = 0) + 2; k <= count; k += 2) {                int hi = run[k], mi = run[k - 1];                for (int i = run[k - 2], p = i, q = mi; i < hi; ++i) {                    if (q >= hi || p < mi && a[p + ao] <= a[q + ao]) {                        b[i + bo] = a[p++ + ao];                    } else {                        b[i + bo] = a[q++ + ao];                    }                }                run[++last] = hi;            }            if ((count & 1) != 0) {                for (int i = right, lo = run[count - 1]; --i >= lo;                    b[i + bo] = a[i + ao]                );                run[++last] = right;            }            int[] t = a; a = b; b = t;            int o = ao; ao = bo; bo = o;        }    }

代码很长,简要翻译过来,这里分了好几种情况:

数组长度小于286

这里又会调用一个sort方法,点开该sort(),又会划分情况:

数组长度小于47,

当leftmost(导入的一个布尔参数)为true,则使用直接插入排序;

否则会调用另一种插入办法,这里可以观察到一个注释:

大致意思是:相邻部分的每个元素都扮演着哨兵的角色,因此这允许我们避免在每次迭代中进行左范围检查。此外,我们使用了更优化的算法,即所谓的成对插入排序,它比插入排序的传统实现更快(在快速排序的上下文中)。

不过注意到,原函数参数传参在这里leftmost为true,所以一定是直接插入排序,以上作为了解。

至于大过INSERTION_SORT_THRESHOLD(47)的,用一种快速排序的方法:

从数列中挑出五个元素,称为 “基准”(pivot);

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

递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

当数组长度大于286时

此时回到那段很长很长的代码段,在判断小于286的长度数组之后,从注解中:

// Check if the array is nearly sorted

这里是指检查数组元素是不是快要排列好了,或者书面一点说,是不是有一定结构了,然后看后面的for循环,注意到一段代码:

 if (++count == MAX_RUN_COUNT) {                sort(a, left, right, true);                return;            }

这里的sort和我们上面在数组长度小于286时的那个sort方法是同一个方法,而针对这个count,是用来记录逆序组的,打个比方:

此时有一个数组为1 5 6 9 8 7 2 3

当数组认定我们的顺序应该为升序时,从第一个数开始数,此时9 8 7 2为降序,这就是逆序,将这四个数组合成一个组称为逆序组,然后再从3开始往后看。

当统计到一个逆序组时,count++,所以可以看出,count是用来记逆序组的,那么逆序组越多,这个结构就越混乱

MAX_RUN_COUNT == 67 ,因此当count一直加到67时,就说明已经在一个混乱的临界值了,此时执行sort()方法

通过这一段分析,我们理一下思路:

如果数组能运行到这里,说明数组的长度大于等于286。符合该条件时,我们要判断这个数组是否有一定的结构:

(1)count<67,说明不是那么混乱,有一定结构,跳过;

(2)count>=67,说明已经混乱了,没有结构,执行sort方法,而已知数组长度大于等于286,那么必然大于47,一定执行快速排序。

跳过之后,经过代码的一大堆前置操作,最后看见下面的代码里面一行注释:

//Merging

显然,这里后面用到归并排序了,不详细赘述。

好了,最后总结:

  • 数组长度小于286时,根据数组长度,分两种情况:

    • 数组长度小于47,使用直接插入排序

    • 数组长度大于47,使用快速排序

  • 数组长度大于286时,根据数组排序情况,分两种情况:

    • 数组内顺序较为混乱,即count逆序组数大于等于67,使用快速排序

    • 数组内有一定顺序,即count逆序组数小于67,使用归并排序

“Arrays.sort(arr)代码逻辑是什么”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Arrays.sort(arr)代码逻辑是什么

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Arrays.sort(arr)代码逻辑是什么

本篇内容介绍了“Arrays.sort(arr)代码逻辑是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!首先看源码: public st
2023-06-29

模糊逻辑是什么?

模糊逻辑是一种处理不确定性和模糊信息的数学理论,用于处理模糊集合和模糊推理,其中元素的隶属度是连续的,而不是二值的。模糊逻辑广泛应用于控制系统、决策支持系统、专家系统、图像处理和自然语言处理等领域。虽然模糊逻辑具有处理不确定性、鲁棒性和解释能力等优点,但它也存在计算复杂性、主观性和可解释性方面的缺点。
模糊逻辑是什么?
2024-04-02

python短路逻辑是什么

短路逻辑是一种在条件语句中使用逻辑运算符时的行为规则。在Python中,短路逻辑是指当使用"and"和"or"逻辑运算符时,如果表达式的值已经根据前面的部分确定了结果,则不再计算后面的部分。具体来说,当使用"and"运算符时,如果第一个表达
2023-08-15

SEO逻辑指的是什么

这篇文章给大家分享的是有关SEO逻辑指的是什么的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。  众所周知,SEO行业在刚萌芽的时候,其发展速度是相当快的,犹如坐火箭一般,操作起来也是容易的很,简单的关键词叠加、软
2023-06-10

mysql逻辑主键是什么

mysql逻辑主键是指在数据库中用于标识一条记录的字段或字段组合,但是它并不是唯一的。逻辑主键通常被用于数据查询和数据操作。逻辑主键可以是任何具有标识性质的字段,比如在用户表中,用户名可以作为逻辑主键,因为它可以用于标识一条记录,但是它并不
2023-07-10

jmeter逻辑控制器是什么

本篇内容主要讲解“jmeter逻辑控制器是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“jmeter逻辑控制器是什么”吧!Jmeter逻辑控制器(Logic Controller)介绍:1、
2023-06-05

什么是LVM逻辑卷管理

什么是LVM逻辑卷管理,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。  Linux因其开放性而受到许多企业和开发者的喜爱,it互联网市场相应的也增加了对Linu
2023-06-05

MySQL三层逻辑架构是什么

小编给大家分享一下MySQL三层逻辑架构是什么,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!MySQL三层逻辑架构MySQL的存储引擎架构将查询处理与数据的存储/
2023-06-27

kafka核心消费逻辑是什么

这篇文章主要介绍“kafka核心消费逻辑是什么”,在日常操作中,相信很多人在kafka核心消费逻辑是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”kafka核心消费逻辑是什么”的疑惑有所帮助!接下来,请跟
2023-07-06

todomvc组件编写逻辑是什么

TodoMVC 是一个用来演示各种前端框架编写 todo 应用的开源项目。在 TodoMVC 中,每个框架都有自己的组件编写逻辑,但是它们通常都包含以下几个方面的逻辑:初始化:在组件的生命周期中,需要进行一些初始化的工作,比如获取初始数据、
2023-10-23

php逻辑运算符是什么意思

在php中,逻辑运算符是进行逻辑运算的一种符号,可用来组合逻辑运算的结果,是程序设计中一组非常重要的运算符;逻辑运算符有6种:“and”和“&&”表示逻辑与、“||”和“or”表示逻辑或、“xor”表示逻辑异或、“!”表示逻辑非。
2014-05-03

Hybris CommerceUI tag的渲染逻辑是什么

这篇文章主要介绍“Hybris CommerceUI tag的渲染逻辑是什么”,在日常操作中,相信很多人在Hybris CommerceUI tag的渲染逻辑是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答
2023-06-04

Node.js模块的加载逻辑是什么

这篇文章主要介绍Node.js模块的加载逻辑是什么,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一、按照组织方式划分模块文件模块:是我们上一章节说过的,就是一个独立的.js文件。目录模块:是我们可以将多个独立的.js
2023-06-26

Linux进程调度的逻辑是什么

这篇文章主要介绍“Linux进程调度的逻辑是什么”,在日常操作中,相信很多人在Linux进程调度的逻辑是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Linux进程调度的逻辑是什么”的疑惑有所帮助!接下来
2023-06-29

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录