初級排序算法1-定義排序規則
初級排序算法-定義排序規則
排序就是將一組對象按照某種邏輯序列重新排列的過程.
Table of contents
- 介紹
- 為什麽學它
- 排序算法類的模板
- 驗證
- 性能評估
介紹
現在計算機的廣泛使用使得數據無處不在,而整理數據的第一步通常就是進行排序
所有的計算機都實現了各種排序算法以供系統和用戶使用
為什麽學它
即使你只是使用標準庫中的排序算法,學習排序算法仍然有三大實際意義
- 對排序算法的分析將有助於你全面理解比較算法性能的方法
- 類似的技術也能有效解決其他類型的問題
- 排序算法常常是我們使用算法解決其他問題的第一步
排序算法類的模板
package algorithms4.sort; import edu.princeton.cs.algs4.In; public class Example { public static void sort(Comparable[] a){ //排序算法 } private static boolean less(Comparable v, Comparable w){ return v.compareTo(w) < 0; } private static void exch(Comparable[] a, int i, int j){ Comparable t = a[i]; a[i] = a[j]; a[j] = t; } private static void show(Comparable[] a){ //在單行中打印數組 for (int i = 0; i < a.length; i++) { System.out.println(a[i] + " "); } System.out.println(); } public static boolean isSorted(Comparable[] a){ //測試數組元素是否有序 for (int i = 0; i < a.length; i++) { if (less(a[i], a[i -1])) { return false; } } return true; } public static void main(String[] args) { //從標準輸入讀取字符串,將他們排序並輸出 String[] a = new In("需要排序的數據文件").readAllStrings(); sort(a); assert isSorted(a); show(a); } }
我們會將排序算法放在類的sort()方法中,該類還將包含輔助函數less類()和exch()(可能還會有其他輔助函數)以及一個示例用例main()
為了區別不同的排序算法,我們為相應的類取了不同的名字,例如Insertion.sort(),Merge.sort(),Quick.sort()等
這個類展示的是數組排序實現的框架,對於我們學習的每種排序算法,我們都會為這樣一個類實現一個sort()方法並將example改為算法的名稱
驗證
通過assert isSorted(a);來確認排序後的數組元素都是有序的,盡管一般都會做簡單地測試,並從數學上證明算法的正確性,但是實現每個算法時加上這條語句仍是必要的
如果我們只使用exch()來交換數組的元素,這個測試就足夠了
但是當我們直接將值存入數組的方式(也就是原數組不變,得到另一個排序數組)
這條語句就無法提供足夠的保證了(例如,憑空造出一個1,2,3數組,哈哈)
性能評估
運行時間.評估算法的性能,計算各個排序算法在不同的隨機輸入下的基本操作的次數(包括比較和交換,或者是讀寫數組的次數)
在研究排序算法時,我們需要計算比較和交換的數量,對於不交換的算法,我們會計算訪問數組的次數
額外的內存使用
排序算法的額外內存開銷和運行時間是同樣重要的
排序算法可以分為兩類
- 除了函數調用所需的棧和固定數量的實例變量之外無須額外內存的原地排序算法
- 以及需要額外內存
數據類型
我們的排序算法模板適用於任何實現了Comparable接口的數據類型,遵循java慣例的好處是,很多你希望排序的數據都實現了comparable接口,例如基本類型,以及String和其他許多高級數據類型,(如file和url)都實現了comparable接口
因此,可以直接使用這些類型的數組作為參數調用我們的排序方法
在創建自己的數據類型時,我們只需要實現Comparable接口就能保證用例代碼將其排序
實現compatable接口中的compareTo方法來定義目標對象類型的自然排序規則
如下面的date數據類型(@Data註解轉向另一篇博客lombok)
package algorithms4.sort;
import lombok.Data;
@Data
public class DateExample implements Comparable<DateExample> {
private final int month;
private final int day;
private final int year;
public DateExample(int d, int m, int y){
day = d;
month = m;
year = y;
}
@Override
public int compareTo(DateExample that) {
if (this.year < that.year) {
return -1;
} else if (this.year > that.year) {
return 1;
} else if (this.month < that.month) {
return -1;
} else if (this.month > that.month) {
return 1;
} else if (this.day < that.day) {
return -1;
} else {
return this.day > that.day ? 1 : 0;
}
}
@Override
public String toString(){
return year + "/" + month + "/" + day;
}
}
compareto必須實現一個完整的比較接口
數學意義上
當兩個元素滿足
1.自反性,對於所有的v,v=v
2.反對稱性,有v<w情況的存在,都有v>w的情況存在
3.傳遞性,如果v<=w,且w<=x,則v<=x
compareto實現了我們的主鍵抽象,它給出了實現了comparable接口的任意數據類型的對象的大小順序的定義
初級排序算法1-定義排序規則