折半插入排序(二分插入排序),也是插入排序的一種,利用二分法的思想去尋找元素應該在的位置
平均時間複雜度:O(n^2)
最好時間複雜度:O(nlgn) // 數組完全有序
最壞時間複雜度:O(n^2) // 數組完全逆序
空間複雜度:O(1)
算法穩定性:穩定
上代碼:
public class 二分法插入排序 {
private static int[] data;
/**
* 把data數組從小到大進行排序
*/
public static void Sort() {
for (int i = 1; i < data.length; i++) { // 每次循環都是查找 data[i]這個int值 應該在的位置
// 循環開始 定義查找的範圍 (0,i-1),之所以end爲 i-1 ,因爲當前需要尋找位置的數是 i,範圍從它前面開始
int start = 0, end = i - 1, mid;
int key = data[i];
while (start <= end) { // 這個循環目的是查找data[i]應該在的位置
// 循環結束的end一定是大於start 怎麼去證明呢?
// 假設最後一個mid大於key,那麼end前移,所以最後一個mid就是key所在的位置,final position =
// end +`1
// 假設最後一個mid小於key,那麼start後移,最後一個mid之前的位置就是final position= end +
// 1
// 則最後放置位置是 end+1
mid = (start + end) / 2;
if (data[mid] > key) { // 小於中點值,則後面指針前移
end = mid - 1;
} else { // 大於中點值,則前面指針後移
start = mid + 1;
}
}
// 由於final position前面數組已經有序,所以所以把final position及其之後的元素後移
for (int j = i - 1; j >= end + 1; j--) {
data[j + 1] = data[j]; // 之前的範圍最後一位是 i-1,所以i-1+1的位置等於i-1,依次類推
}
data[end + 1] = key;
}
}
/**
*
* 用增強for循環輸出當前數組
*/
public static void PrintData() {
for (int i : data) {
System.out.print(" " + i);
}
System.out.println("");
}
public static void main(String[] args) {
data = new int[10];
System.out.println("輸入十個數 進行直接插入排序");
Scanner scanner = new Scanner(System.in);
for (int i = 0; i < 10; i++) {
data[i] = scanner.nextInt();
}
Sort();
PrintData();
scanner.close();
}
}