簡體   English   中英

排序數組的最快方法,無需覆蓋它

[英]Fastest way to sort an array without overwriting it

我想在Java中對int[] array進行排序,但是將已排序的數組存儲為新數組而不是覆蓋它。

最明顯的方法是創建數組的副本,然后對新數組進行排序,如下所示:

int[] a2 = new int[a.length];

for (int i = 0; i < this.length; i++) {
    a2[i] = a[i];
}

Arrays.sort(a2);

但是,有更快的方法嗎? 我們可以在“同時”排序,因為我們將舊數組的元素復制到新數組中嗎?

你可以用

int[] a2 = IntStream.of(a).sorted().toArray();

但我懷疑它比它更快

int[] a2 = a.clone();
Arrays.sort(a2);

無論它的復雜程度如何,因此不要期望超過恆定因子加速。

在迭代舊數組時對新數組進行排序將不會更快。 為此,您可以使用System.arraycopy()而不是創建自己的排序或復制功能。

將指定源數組中的數組從指定位置開始復制到目標數組的指定位置。

例:

int[] a1 = new int[]{1,2,3,4,5};  // I suppose a1...
int[] a2 = new int[a1.length];

System.arraycopy( a1, 0, a2, 0, a1.length );

Arrays.sort(a2);

更新:只要您要求更快的方式對數組進行排序,正如您所看到的那樣,長期討論是否復制它或動態排序將是最佳選擇。 為此你可以嘗試做一些基准測試。 但是如果你使用copy來對它進行排序, 你會發現這里所有都取決於數組的大小和元素

如果您傾向於使用TreeSet ,則以下代碼TreeSet目的:

TreeSet<Integer> copied = new TreeSet<>();
for (int i = 0; i < array.length; i++) {
    copied.add(i);
}

我試圖測試差異,它實際上取決於數據的大小以及數組中的數據。

但是,我無法評論這種方法的確定性如何,但我肯定會進行一些實驗並在此發布我的發現。

更新:

我使用以下代碼來測試TreeSet的性能

import java.util.Arrays;
import java.util.Random;
import java.util.TreeSet;

class TestArrayCopy {

    public static void main(String[] arg) throws java.io.IOException {
        for (int i = 1; i <= 10; i++) {
            int arr[] = randomArray();
            System.out.println("Array Size: " + arr.length + ". Results for case #" + i);
            System.out.println("Using Array Copy:");
            copyAndSort(arr);
            System.out.println("Using Tree Set:");
            useTreeSet(arr);
            System.out.println("----------------------------");
        }
    }

    public static void copyAndSort(int array[]) {
        long start = System.nanoTime();
        for (int j = 0; j < 100; j++) {
            int copied[] = Arrays.copyOf(array, array.length);
            Arrays.sort(copied);
        }
        long end = System.nanoTime();
        System.out.println(end - start);
    }

    public static void useTreeSet(int array[]) {
        long start = System.nanoTime();
        for (int j = 0; j < 100; j++) {
            TreeSet<Integer> copied = new TreeSet<>();
            for (int i = 0; i < array.length; i++) {
                copied.add(i);
            }
        }
        long end = System.nanoTime();
        System.out.println(end - start);
    }

    public static int[] randomArray() {
        Random random = new Random();
        int len = 100000 + random.nextInt(1000000);
        int arr[] = new int[len];
        for (int i = 0; i < len; i++) {
            arr[i] = random.nextInt(1000000);
        }
        return arr;
    }

}

使用Java 8在Core-i7 64位系統上實現了以下結果:

數組大小:616568。案例#1的結果
使用陣列復制:
7692926921
使用樹集:
16336650396
----------------------------
數組大小:390270。案例#2的結果
使用陣列復制:
4441066232
使用樹集:
9306742954
----------------------------
數組大小:658410。案例#3的結果
使用陣列復制:
8534144532
使用樹集:
17721764026
----------------------------
數組大小:1021396。案例#4的結果
使用陣列復制:
13573512678
使用樹集:
31341152398
----------------------------
數組大小:1034872。案例#5的結果
使用陣列復制:
13298690836
使用樹集:
30950793986
----------------------------
數組大小:466014。案例#6的結果
使用陣列復制:
5501196272
使用樹集:
11704757934
----------------------------
數組大小:190231。案例#7的結果
使用陣列復制:
1662270714
使用樹集:
4465174267
----------------------------
數組大小:681150。案例#8的結果
使用陣列復制:
8262756493
使用樹集:
19079310588
----------------------------
數組大小:627257。案例#9的結果
使用陣列復制:
6725984653
使用樹集:
14468898852
----------------------------
數組大小:397189。案例#10的結果
使用陣列復制:
3122214311
使用樹集:
7356182877
----------------------------

從這些結果可以看出,TreeSet比排序重復數組慢很多。 對我好運動。

int [] a2 = IntStream.of(a).sorted()。toArray();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM