第十三章 查詢與排序
13.1 Java類庫中的查詢與排序
(1) ArrayList或者LinkedList物件,可以呼叫它的indexOf方法來進行查詢. 該方法通過檢查列表中的每一個元素來查詢目標值, 列表如果含有所要查詢的資料, 它將返回第一個符合條件的資料的索引值,否則返回-1.
indexOf方法按順序在列表中查詢所需要的資料,我們通常把這類方法稱為順序查詢.
如果你所要處理的是陣列而非列表,那麼就沒有已經寫好的方法可以完成對它的查找了. 我們需要自己進行編碼來實現所要的功能,或者直接把陣列中的資料賦值給一個List表,然後呼叫indexOf進行查詢.
13.1.1 二分法查詢
對已經排好序的陣列或者列表進行查詢. 有一種更好的叫做二分法查詢的方法,它的查詢速度比順序查詢要快許多. 在Java的類庫中已經實現了對陣列和列表進行二分法查詢的方法. Java.util 包中的Arrays類裡有一個叫做binarySearch的靜態類方法可以用來實現二分法查詢演算法. 它以一個任意型別的陣列和一個目標值作為輸入,並返回目標元素的索引值,如果該元素不存在,則返回一個負值.
如果你用的是像ArraysList一樣的列表, 那麼可以呼叫靜態方法Collections.binarySearch來進行查詢.
13.1.2 排序
Java的類庫中提供了用來對陣列或列表進行排序的方法. 可以用Arrays.sort 方法對陣列進行排序. 用Collections.sort 對列表進行排序. 當處理原始資料時,Arrays.sort 會採用一種叫做快速排序的演算法,而當處理物件資料時,Collections.sort 和 Arrays.sort 方法會採用一種叫做歸併排序的不同演算法.
13.1.3 洗牌
Collections類有一個shuffle的方法可以接收一個列表作為引數,並將其元素以隨機順序排列.
方法 | 描述 |
Arrays.binarySearch(array,value) | 返回給定值在一個已經排好序的陣列中的索引值,如果不存在,則返回負數. |
Arrays.sort(array) | 對給定陣列的元素進行排序 |
Collections.binarySearch(list, value) | 返回給定值在一個已經排好序的列表中的索引值,如果不存在,則返回負數. |
Collections.sort(list) | 對給定列表的元素進行排序 |
Collections.shuffle(list) | 對給定列表的元素進行隨機排序 |
13.1.4 用比較器來自定義順序
有時你會希望以一種與Comparable 的實現不同的順序來對一些物件進行查詢與排序. 很多像字串這樣的資料型別本身就是根據其比較函式定義了順序的,而該函式有是一個叫做compareTo 的方法來實現的. 可以用一個叫做比較器(comparator)的物件來定義我們所需要的順序, 比較器可以用來實現哪些不按照自然順序工作的比較函式, 但是它所比較的兩個物件必須是同一型別的. 一個類最多隻有一種自然順序, 但是可以定義任意多的比較器來描述其物件的比較方式. 比較器還為類提供自然序以外的其他排序規則. Arrays.sort 方法, Collections.sort 方法以及Arrays.binarySearch方法都有一個接收額外的Comparator引數的變體, 並利用該比較器實現相應的查詢與排序功能.
比較器通過實現Java.util 包中的comparator介面來構造. 該介面有個叫做compare的方法, 它以兩個物件為引數並對他們進行比較. 與compareTo 類似, compare方法在比較結果為小於、等於以及大於時,分別返回負值、零和正值.
public interface Comparator<T>{
public int compare(T o1, T o2);
}
實現一個比較器與實現一個Comparable 介面很相似(10.2.2), 只不過你需要構建一個可以接收連個待比較物件為引數的獨立的類,而不是程式碼寫在待比較類的內部. Compare方法與Comparable 介面(10.2.2)中的compareTo方法類似,只不過它接收兩個所要比較的類的物件為引數. (comparable 只接收一個物件作為引數,因為另一個所要比較的物件是隱含引數. )
與Comparable 介面相似,Comparator是個必須被告知所比較物件型別的一般Comparator<T>介面. 例如想好編寫一個處理String的比較函式,必須要構造一個實現了Comparator<String>的類.
下面編寫一個按照字串長度進行排序的比較器.
import java.util.*;
// compares String objects by length
public class LengthComparator implements Comparator<String> {
public int compare(String s1, String s2) {
return s1.length() – s2.length();
}
}
現在有了一個長度比較器,就可以對string型別的陣列或列表進行排序時傳遞一個作為引數:
Arrays.sort(string, new LengthComparator());
比較器的優點: 無需對被比較的類進行修改.
比較器/方法 | 描述 |
Arrays.binarySearch(array,value, comparator) | 返回給定值在一個已經按照比較器的順序排好序的陣列中的索引值,如果不存在,則返回負數. |
Arrays.sort(array, comparator) | 按照比較器的順序對給定陣列的元素進行排序 |
Collections.binarySearch(list, value, comparator) | 返回給定值在一個已經按照比較器的順序排好序的列表中的索引值,如果不存在,則返回負數. |
Collections.sort(list, comparator) | 按照比較器的順序對給定列表的元素進行排序 |
Collections.max(collection,comparator) | 返回按照給定比較器的順序定義的資料集中的最大值 |
Collections.min(collection,comparator) | 返回按照給定比較器的順序定義的資料集中的最小值 |
Collections.reverseOrder() | 返回一個按照與自然序相反的順序進行比較的比較器 |
Collections.reverseOrder(comparator) | 返回一個按照與給定比較器順序相反的順序進行比較的比較器 |
String.CASE_INSENTIVE_ORDER | 一個按照字母順序而且與大小寫無關的比較器 |
13.2 程式的複雜度
演算法分析是一種利用數學工具預測與計算演算法效能的技術與方法.
為了方便起見,我們假設下面的這些操作都恰好需要一個單位的時間來執行:
- 變數的宣告與賦值.
- 算術與邏輯表示式的計算.
- 訪問或修改陣列中的一個元素.
- 一些簡單的演算法呼叫.