選擇排序算法是經典算法之一,你可以想象你在打牌,每次拿到的一張牌就是待排序的一張,你需要每一次跟之前的牌進行比較,然後將這張牌插入到合適的位置。那麼選擇排序也是一樣,將整個數組看成兩個部分,有序部分和無序部分。現在需要將無序部分的數字跟有序部分進行比較,插入到正確的位置
下列代碼是插入排序的內層循環:
while (insertIndex >= 0 && insertVal < arr[insertIndex]) {
arr[insertIndex + 1] = arr[insertIndex];
insertIndex--;
}
while循環中判斷用來控制當前數字是否比有序部分前一個數字小,和必須要滿足有序部分的前一個索引是大於0的否則就會出現越界。循環裏面進行數值的賦值。意義在於當判斷成立之後,則代表當前數字是比有序部分的數字小,那麼需要進行移位,即把前一個數字賦值給後一個數字,然後再將下標前移。下面放完整代碼:
public static void insertSort(int[] arr) {
for (int i = 1; i < arr.length; i++) {
//需要進行插入操作的數
int insertVal = arr[i];
int insertIndex = i - 1;
while (insertIndex >= 0 && insertVal < arr[insertIndex]) {
arr[insertIndex + 1] = arr[insertIndex];
insertIndex--;
}
arr[insertIndex + 1] = insertVal;
}
}
最後來測試一下本算法在處理10w條數據的處理時間
public static void main(String[] args) {
int[] arr = new int[100000];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) (Math.random() * 8000000);
}
// System.out.println(Arrays.toString(arr));
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String start = sdf.format(new Date());
System.out.println(start);
insertSort(arr);
String end = sdf.format(new Date());
System.out.println(end);
}
最終的運行結果爲:
但是選擇排序算法是可以進行優化的,舉個例子
{2,3,4,5,6,7,8,9,1} 像現在這組數據,如果按照傳統的插入排序,最後一位數字進行判斷和移位時會出現大量移位。那麼爲了解決這個問題就需要設置一個步長,利用步長將數組分爲多個小數組進行插入排序。這樣就可以將這個問題進行簡化。
具體代碼如下:
public static void shellSort(int[] arr) {
for (int step = arr.length / 2; step > 0; step /= 2) {
for (int i = step; i < arr.length; i++) {
int j = i;
int value = arr[i];
if (arr[j] < arr[j - step]) {
while (j - step >= 0 && value < arr[j - step]) {
arr[j] = arr[j - step];
j -= step;
}
arr[j] = value;
}
}
}
}
代碼中第一層循環是控制步長循環,這樣就可以將數組分爲若干個小數組,在步長爲1時這時的數組就變成了一個基本有序的數組,這樣再對這個數組進行排序效率明顯就提升了許多。
最後來測試一下本算法在處理10w條數據的處理時間
public static void main(String[] args) {
int[] arr = new int[100000];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) (Math.random() * 8000000);
}
// System.out.println(Arrays.toString(arr));
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String start = sdf.format(new Date());
System.out.println(start);
shellSort(arr);
String end = sdf.format(new Date());
System.out.println(end);
}
最終的運行結果爲:
可以很明顯得看出這個算法的效率還是很高的。