插入排序
我們有了選擇排序,冒泡的基礎了,我還是說一下我對排序算法的認識吧,感覺排序這個東西嘛,在我們日常的代碼中可能用哪種差別不是特別的大,但是如果要處理很多數據的時候,排序的重要性便體現出來了,而且我認爲基礎算法和編程的基礎是我們每個人都應該具備的知識吧,所以認真的分析一下還是有一點點必要的。
然後我想說的就是插入排序的思想,插入排序的思想和我們在鬥地主的時候喜歡將牌從大到小的排列的思想是一致的,我們會選出一張牌放到相應的位置,從某種意義上講,如果在數據的可序性較高的時候,插入排序是效率最高的一種排序的方式。
package paixu;
public class Insertion {
public static void sort(Comparable[] a) {
int N = a.length;
for (int i = 1; i < N; i++) {
for (int j = i; j > 0 && less(a[j], a[j - 1]); j--) {
exch(a, j, j - 1);
}
}
}
public 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;
}
public 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 = 1; i < a.length; i++)
if (less(a[i], a[i - 1]))
return false;
return true;
}
public static void main(String[] args) {
String[] a = "B,D,C,A,E,G,F, ".split(",");
sort(a);
assert isSorted(a);
show(a);
}
}
當然根據我們的代碼,可想而知我們的輸出的結果是按照順序排好的A,B,C,D,E,F,G,我們這裏並不是單純的把所有代碼都羅列到主函數裏面,這裏面用到的函數的類的思想非常的明顯,這樣寫的好處是,如果我們想實現其它排序的話只需要非常簡單的修改一點代碼即可。
這裏我們主要起到排序作用的代碼是我們的sort函數,在這裏我們採用兩個for循環,外層循環控制i的位置,當我們的i,在第二個數的時候會判斷和第一個數的關係,如果比第一個數大,則保持不變,如果比第一個小則交換位置,這個時候我們的數組中前兩個字符便有了順序,之後我們會對數組裏面其它的字符進行判斷,看它要插入到哪兩個字符之間,這樣便完成了我們的插入排序,當然插入的過程中並不是直接插入的,而是每兩個都要判斷一看,看一下具體要插在哪裏。
我們的less函數,返回的值是一個boolean類型的數值,這裏面用到了一個comparable的函數,此方法如果這個字符串是等參數字符串那麼返回值0,如果這個字符串是按字典順序小於字符串參數那麼返回小於0的值,如果此字符串是按字典順序大於字符串參數那麼一個大於0的值。
我們的exch函數的目的是爲了判斷的,是用來將兩個數據的值進行交換的。
我們的show函數的目的是,將排序好的數組輸出在屏幕上面。
我們的isSorted是一個判斷,用來判斷我們的排序是否成功的,如果我們的排序成功了,那麼將返回一個true,如果排序失敗了,那麼我們將返回一個false。
我們的main函數中我們創建了一個string類型的數組,是將一個字符串通過split的方式變成的string類型的數組,然後調用我們的排序的方法,下面我們還涉及到一個重點就是斷言的方法,也就是說,如果我們斷言後面返回的是真的話,那麼我們就執行下面的操作,也就是輸出我們的結果,如果我們發現排序失敗了,那麼我們的斷言將會起作用,這個時候我們會拋出一個異常,也就不會有結果的輸出了。
當我們掌握了冒泡排序,選擇排序,插入排序之後,我們已經掌握了排序算法中最爲基礎的幾種排序了,在我日後的博客中還會爲大家更新一些較爲複雜的排序方式。