java 数组排序论文_Java 7是否对方法Arrays.Sort使用Tim Sort?
是! ...也沒有
摘要
在當前的Open JDK 0實現中,Tim Sort通常用于對對象數組(即byte和好友)進行排序-但是對于基本數組(byte方法的其余部分)使用了多種其他方法。
對于基元,試探法可在各種排序方法中進行選擇,例如快速排序,合并排序,計數排序3。 取決于要排序的數據。 這些決策中的大多數都是根據要排序的數組的類型和大小簡單地預先做出的,但是對于byte和short元素,該決策實際上是根據測得的數組排序進行自適應的。 因此,在許多情況下,您會在適應/自省(TimSort或類似的合并排序)之上擁有適應/自省(啟發(fā)式算法選擇算法)!
細節(jié)
除非用戶已通過將系統屬性short設置為true來明確請求舊版行為,否則Tim排序可用于大多數對象,例如byte。
對于基元,情況更加復雜。 至少從JDK 8(版本byte)開始,根據要排序的數組的大小,原始類型和所測得的數組的“排序度”,使用了各種試探法。 以下是概述:
對于字節(jié)1以外的所有基本類型,少于47個元素的數組都使用插入排序進行了簡單排序(請參閱byte)。 當對使用合并或快速排序且子數組的大小降至閾值以下時出現的子數組進行排序時,也會使用此閾值。 因此,某種形式的插入排序將用于各種排序,對于小數組,這是唯一使用的算法。
對于基本類型byte、short和char,計數排序用于較大的數組。 這是一種簡單的排序,需要花費Object[]的時間,其中range是字節(jié)(256)或short / char(65536)值的總數。 排序涉及分配range值的基礎數組,因此僅在要排序的元素數量占總范圍的很大一部分時才使用它。 特別是,它用于大于29個元素的字節(jié)數組(即?11%的范圍)和大于3200個元素的short / char數組(約5%的范圍)。
對于字節(jié)數組,始終使用以上兩種方法之一。
對于高于插入排序閾值的byte和short陣列以及高于插入排序閾值和低于計數排序閾值的char/294872508633081515陣列,可以使用以下兩種算法之一:雙數據點快速排序或合并排序。 使用哪一個取決于對數組排序的度量:將輸入分為升序或降序元素。 如果此類運行的數量大于66,則該數組被認為大部分未排序,并使用雙軸快速排序進行排序。 否則,該數組被認為是最有序的,并使用mergesort(以已經枚舉的運行作為起點)。
盡管有一些區(qū)別,但找到運行然后使用mergesort對它們進行排序的想法實際上與TimSort非常相似。 因此,至少對于某些參數,JDK使用的是運行感知的合并排序,但對于參數的許多其他組合,則使用的是不同的算法,總共至少使用5種不同的算法!
基本原理
byte與原始語言不同的排序行為背后的原因可能至少有兩方面:
1)要求byte的類別必須穩(wěn)定:類別均等的對象將以與輸入相同的順序出現。 對于基元數組,不存在這樣的概念:基元完全由它們的值定義,因此穩(wěn)定和不穩(wěn)定排序之間沒有區(qū)別。 這允許原始排序免除對穩(wěn)定算法的需求,而有利于速度。
2)各種byte需要涉及short方法,這可能是任意復雜和昂貴的。 即使char方法很簡單,除非整個內聯方法都可以內聯2,否則通常會存在方法調用開銷。 因此,即使以一些額外的算法復雜性為代價,通常也會將各種Object[]偏向于使總比較最小化。
另一方面,原始數組的排序只是直接比較原始值,這些原始值通常需要一個或兩個周期。 在這種情況下,應同時考慮比較成本和周圍算法,對算法進行優(yōu)化,因為二者的大小可能相同。
0至少對于Java 7和Java 9之間的版本,當然,它也包括基于Open JDK的Oracle JDK。 其他實現可能也使用類似的方法,但是我沒有檢查。
1對于字節(jié)數組,插入排序閾值實際上是29個元素,因為這是使用計數排序的下限。
2這似乎不太可能,因為它很大。
3計數排序僅用于16位以下的有限范圍內的值:byte、short或char。
總結
以上是生活随笔為你收集整理的java 数组排序论文_Java 7是否对方法Arrays.Sort使用Tim Sort?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 水上飞机的种类和作用(海上救援任务中的水
- 下一篇: m5310模组数据上传至onenet_硬