路人甲:嗨,你好,排小序,我想問你一個問題,好嗎?
排小序:好呀,你問吧,我知道很多關於排序的知識呢,只要你問,我都會告訴你呀
路人甲:問題來嘍,一個有序的數組,往裏面添加一個新的數據後,如何繼續保持數據有序呢?
排小序:嗯嘛嘛,這個嘛,是這樣的,很簡單,只要遍歷數組,找到數據應該插入的位置將其插入即可。怎麼樣,我厲害吧
路人甲:哇塞,你真棒。帶我學習排序吧(害羞)
針對以上排序的經典問題,我們這裏也提出一個經典排序算法,那就是,直接插入排序。
1.核心思想
已排序區間+未排序區間
取未排序區間中的元素,在已排序區間中找到合適的插入位置將其插入,並保證已排序區間數據一直有序。重複這個過程,直到未排序區間中元素爲空,算法結束。
2.算法描述過程
(1)從第一個元素開始,該元素可以認爲已經被排序;
(2)取出下一個元素,在已經排序的元素序列中從後向前掃描;
(3)如果該元素(已排序)大於新元素,將該元素移到下一個位置;
(4)重複步驟3,直到找到已排序的元素小於或者等於新元素的位置;
(5)將新元素插入到該位置後;
(6)重複步驟2-5
3.代碼實現
3.1直接插入排序代碼實現
public static void insertSort(int[] array){
if(array.length <= 1){
return;
}else{
for(int i = 1;i < array.length;i++){
//有序區間:[0,i)
//無序區間:[i,array.length)
int value = array[i];
int j = i-1;
for(;j >= 0 && array[j] > value;j--){
array[j+1] = array[j];
}
array[j+1] = value;
}
}
}
3.2接下來測試一下下
爲了檢測排序結果的重要性,可以通過Arrays.sort()內置方法來測試一下
public static void main(String[] args) {
int[] a = {2,5,1,7,3,6,9};
//將數組a克隆後賦給數組b
int[] b = a.clone();
insertSort(b);
System.out.println(Arrays.toString(b));
//通過Arrays.sort進行驗證排序結果
int[] c = a.clone();
Arrays.sort(c);
System.out.println(Arrays.toString(c));
System.out.println(Arrays.equals(b,c));
}
結果是這樣的:
哈,明顯的看出,我們的直接插入排序代碼實現是正確的(噓,真是優秀)
3.3測試一下排序速度
爲了更明顯的看出直接插入排序算法的性能,隨機生成10萬個數據的數組來測試排序速度
public static void testSpeed(){
Random random = new Random(20191019);
int[] a = new int[100000];
for (int i = 0;i < 100000;i++){
a[i] = random.nextInt(200000);
}
long begin = System.nanoTime();
insertSort(a);
long end = System.nanoTime();
double s = (end-begin)/1000/1000/1000;
System.out.printf("一共耗時:%.5f 秒%n",s);
}
運行後,會發現,竟然只要這麼短的時間,是不是提高了人工排序的效率呢?
好了,只要五秒就可以對10萬個數據進行排序,是不是很優秀呢?(是的,很棒呀)
期待留言或者分享呀
呀,忘記源代碼了,在這裏呀:
package sort.insertSort;
import java.util.Arrays;
import java.util.Random;
/**
* @Author:Star
* @Date:Created in 9:24 2019/10/19
* @Description:直接插入排序
* 時間複雜度:最好O(n)平均:O(n^2)最壞:(n^2)
* 空間複雜度:O(1)(原地排序)
* 穩定性:穩定
*/
public class Sort {
public static void insertSort(int[] array){
if(array.length <= 1){
return;
}else{
for(int i = 1;i < array.length;i++){
//有序區間:[0,i)
//無序區間:[i,array.length)
int value = array[i];
int j = i-1;
for(;j >= 0 && array[j] > value;j--){
array[j+1] = array[j];
}
array[j+1] = value;
}
}
}
public static void main(String[] args) {
/*
int[] a = {2,5,1,7,3,6,9};
int[] b = a.clone();
insertSort(b);
System.out.println(Arrays.toString(b));
//通過Arrays.sort進行驗證排序結果
int[] c = a.clone();
Arrays.sort(c);
System.out.println(Arrays.toString(c));
System.out.println(Arrays.equals(b,c));*/
testSpeed();
}
public static void testSpeed(){
Random random = new Random(20191019);
int[] a = new int[100000];
for (int i = 0;i < 100000;i++){
a[i] = random.nextInt(200000);
}
long begin = System.nanoTime();
insertSort(a);
long end = System.nanoTime();
double s = (end-begin)/1000/1000/1000;
System.out.printf("一共耗時:%.5f 秒%n",s);
}
}
一起進步,一起學習,加油加油