Java_集合操作_多種最值算法,適時選擇

對一批數據進行排序,然後找出其中的最大值或最小值,這是基本的數據結構知識。在Java中我們可以通過編寫算法的方式,也可以通過數組先排序再取值的方式來實現。下面以求最大值爲例,解釋一下多種算法。

1.自行實現,快速查找最大值
先來看用快速查找法取最大值的算法,其代碼如下:

    public static int max(int[] data) {
        int max = data[0];
        for (int i : data) {
            max = max > i ? max : i;
        }
        return max;
    }

這是我們經常使用的最大值算法,也是速度最快的算法。它不要求排序,只要遍歷一遍數組即可找出最大值。
2.先排序,後取值
對於求最大值,也可以採用先排序後取值的方式,同樣比較簡單,代碼如下:

    public static int max(int[] data) {
        int[] copyArray = data.clone();
        Arrays.sort(copyArray);
        return copyArray[copyArray.length - 1];
    }

從效率上來講,當然是自己寫快速查找法更快一些了,只用遍歷一遍就可以計算出最大值。但在實際測試中我們發現,如果數組數量少於1萬,兩種基本上沒有差別,在同一個毫秒級別內,此時就可以不用自己寫算法了,直接使用數組先排序後取值的方式。
如果數組元素超過1萬,就需要依據實際情況來考慮:自己實現,可以提升性能;先排序後取值,簡單,通俗易懂。排除性能上的差異,兩者都可以選擇,甚至後者更方便一些,也更容易想到。
現在問題來了,在代碼中爲什麼要先使用data.clone排序呢?那是因爲數組也是一個對象,不拷貝不就改變了原有數組元素的順序嗎?除非數組元素的順序無關緊要。
接着往下思考,如果要查找僅次於最大值的元素(也就是老二),該如何處理呢?要注意,數組的元素是可以重複的,最大值可能是多個,所以單單一個排序然後取倒數第二個元素是解決不了問題的。
此時,就需要一個特殊的排序算法了,先要剔除重複數據,然後再排序。當然,自己寫算法也可以實現,但是集合類已經提供了非常好的方法,要是再使用數組自己寫算法就顯得有點過時了。數組不能剔除重複數據,但Set集合卻是可以的,而且Set的子類TreeSet還能自動排序。代碼如下:

    public static int getSecond(Integer[] data) {
        // 轉換爲列表
        List<Integer> dataList = Arrays.asList(data);
        // 轉換爲TreeSet,刪除重複元素並升序排列
        TreeSet<Integer> ts = new TreeSet<Integer>(dataList);
        // 取得比最大值小的最大值,也就是老二了
        return ts.lower(ts.last());
    }

刪除重複元素並升序排列,這都由treeSet類實現的,然後可再使用lower方法尋找小於最大值的值。大家看,上面的程序非常簡單吧?那如果是我們自己編寫代碼會怎麼樣?那至少要遍歷數組兩遍才能計算出老二的值,代碼的複雜度將大大提升。
也許你會說,這個要求有點變態,怎麼會有這樣的需求?不,有這樣的需求很正常,比如在學校按成績排名時,如果一個年級有1200人,只要找出最高的三個分數(可不一定就是3個人,也可能是多人),是不是就是這種情況呢?因此在實際應用中求最值,包括最大值、最小值、第二大值、倒數第二小值等,使用集合是最簡單的方式,當然若從性能方面來考慮,數組是最好的選擇。

發佈了133 篇原創文章 · 獲贊 11 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章