[英]What is the time complexity of java.util.Collections.sort() method?
[英]Racing java.util.Collections.sort
我發現了一種效率更高的排序算法,該算法具有O(N)的平均性能和最佳性能,而O(N Log(N))的性能最差。 關於均勻分布的數據 。
我需要您的幫助來告訴我測試是否正確,我最大的問題是:如何在真實數據上進行測試?
這個問題將包括五個部分:
Java在Collections.sort實現中使用模式化的合並排序算法。 從jdk 7開始,它已被 timsort 取代 。 在測試中,我一直在研究jdk6。與Android相同。
我找到了一種有趣的排序方法。 我使用統計排序。 或更確切地說是線性統計排序。 我假設所有變量都具有“良好”的線性回歸 。 因此,我正在基於變量的值計算其近似索引。 如果多個變量具有相同的索引,則將其放在緩沖區數組中。 比我使用Collections.sort()對緩沖區排序。 想法是緩沖區將非常小,因此排序將為〜O(1)。 這是O(N)和O(N Log(N))的性能之間的差異,在最壞的情況下,它的大小為N。此后,我在近似排序的數組和緩沖區之間合並。 結果是排序數組。
public class StatisticSort {
private static long minemum;
private static long sum;
public static void sort(List<Integer> source) {
findMinMaxAndSum(source);
int size = source.size();
ArrayList<Integer> buffer = new ArrayList<Integer>();
Vector<Integer> sourceVector = new Vector<Integer>(size);
sourceVector.setSize(size);
for (int i = 0; i < size; i++) {
Integer ai = source.get(i);
int index = calculateIndex(ai, source);
if (index != i && sourceVector.get(index) == null) {
sourceVector.set(index, ai);
}
else {
buffer.add(ai); // value
}
}
Collections.sort(buffer);
int bufferSize = buffer.size();
for (int i = 0, j = 0, counter = 0; i < size || j < bufferSize;) {
if (i < size && j < bufferSize) {
Integer ai = sourceVector.get(i);
while (ai == null && i < size) {
i++;
if (i < size) {
ai = sourceVector.get(i);
}
}
if (i == size) {
continue;
}
Integer aj = buffer.get(j);
if (aj < ai) {
source.set(counter, aj);
j++;
}
else {
source.set(counter, ai);
i++;
}
counter++;
}
else {
if (i < size) {
Integer ai = sourceVector.get(i);
if (ai != null) {
source.set(counter, ai);
counter++;
}
i++;
}
else if (j < bufferSize) {
Integer aj = buffer.get(j);
source.set(counter, aj);
j++;
counter++;
}
}
}
}
private static int calculateIndex(Integer ai, List<Integer> source) {
int size = source.size();
return Math.min(size - 1, (int) (((ai - minemum) * size * (size - 1)) / (2 * (sum - size * minemum))));
}
private static void findMinMaxAndSum(List<Integer> source) {
long minemum = Long.MAX_VALUE;
long maximum = -Long.MAX_VALUE;
long sum = 0;
for (int value : source) {
sum += value;
if (value < minemum) {
minemum = value;
}
if (value > maximum) {
maximum = value;
}
}
StatisticSort.minemum = minemum;
StatisticSort.sum = sum;
}
}
public abstract class Test {
protected ArrayList<ArrayList<Integer>> buffer;
private final Random random = new Random();
public int numberOfTests = 100;
public int maxValue = 1000;
public int numberOfItems = 100;
protected void createBuffer() {
buffer = new ArrayList<ArrayList<Integer>>();
for (int i = 0; i < numberOfTests; i++) {
ArrayList<Integer> list = new ArrayList<Integer>();
addRandomNumbers(list);
buffer.add(list);
}
}
protected void createBuffer(int...parametes) {
buffer = new ArrayList<ArrayList<Integer>>();
ArrayList<Integer> list = new ArrayList<Integer>();
for(int i = 0; i < parametes.length; i++){
list.add(parametes[i]);
}
buffer.add(list);
}
protected void addRandomNumbers(ArrayList<Integer> list) {
for (int i = 0; i < numberOfItems; i++) {
int value = random.nextInt(maxValue);
list.add(value);
}
}
protected ArrayList<ArrayList<Integer>> cloneBuffer() {
ArrayList<ArrayList<Integer>> clonedBuffer = new ArrayList<ArrayList<Integer>>();
for(int i = 0; i < buffer.size(); i++){
ArrayList<Integer> clonedList = new ArrayList<Integer>();
ArrayList<Integer> list = buffer.get(i);
for(int element : list){
clonedList.add(element);
}
clonedBuffer.add(clonedList);
}
return clonedBuffer;
}
public abstract void test();
}
性能測試
public class TestPerformance extends Test{
private final Timer timer = new Timer();
public void test() {
createBuffer();
timer.reset();
testSystem();
timeResoult("System");
timer.reset();
testMy();
timeResoult("My List");
}
public void test(int numberOfTests) {
long myTotalTime = 0;
long systemTotalTime = 0;
for(int i = 0; i < numberOfTests; i++){
createBuffer();
timer.reset();
testSystem();
long systemTime = timeResoult();
systemTotalTime += systemTime;
timer.reset();
testMy();
long myTime = timeResoult();
myTotalTime += myTime;
System.out.println("My Time / System Time = " + myTime + " / " + systemTime + " = \t" + ((double) myTime / systemTime));
}
System.out.println("My Time / System Time = " + ((double) myTotalTime / systemTotalTime));
}
private long timeResoult() {
return timeResoult(null);
}
private long timeResoult(String source) {
long time = timer.check();
if (source != null) {
System.out.println(source + ">\tTime: " + time);
}
return time;
}
private void testMy() {
ArrayList<ArrayList<Integer>> buffer = cloneBuffer();
for (int i = 0; i < numberOfTests; i++) {
ArrayList<Integer> list = buffer.get(i);
StatisticSort.sort(list);
}
}
private void testSystem() {
ArrayList<ArrayList<Integer>> buffer = cloneBuffer();
for (int i = 0; i < numberOfTests; i++) {
ArrayList<Integer> list = buffer.get(i);
Collections.sort(list);
}
}
}
主要
public static void main(String[] args) {
TestPerformance testBasics = new TestPerformance();
testBasics.numberOfTests = 1000;
testBasics.numberOfItems = 1000;
testBasics.maxValue = 1000000;
testBasics.test(1000);
}
將您的排序與Collections.sort
的算法進行比較存在一個主要問題:
Collections.sort
必然是一個純粹的比較排序 ,它所具有的一種方法是辨別2個對象中的哪個較小,在最壞的情況下,所有比較排序都可證明是下界O(n log n)
您的排序不適用於任意對象,因為您需要一個O(1)估計量,該值將在最終數組中的位置
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.