基礎算法系列之排序演算法-3. 直接插入排序 並用其解決HDU 1106 排序
我們之前已經學習了氣泡排序和二分查詢兩種基本演算法,本篇文章我們將一起學習下一個基礎演算法——直接插入排序演算法。
直接插入排序
直接插入排序,從這個名字來看,是不是讓你想到了什麼場景?!對了,就是打撲克牌的場景,我們每摸一張牌,是不是按照一定的次序插入到現有的牌當中,最後當摸完時,手上的牌就是按一定次序排列了。直接插入排序就是類似我們打撲克牌抓牌的過程。
直接插入排序的演算法思想
直接插入排序跟氣泡排序一樣,是一種最簡單的排序演算法,其基本操作就是講一個數插入到已經排好序的序列中,從而得到一個新的,元素數+1的序列,直到插入完最後一個數,就完成了我們的排序工作。
直接插入排序的實現過程
我們將序列的第一個元素單獨看成一個已知有序序列,逐次將每個數按順序插入到這個序列中,通過n-1(假設有n個數)次迴圈,最後得到我們需要的有序序列。
程式碼實現
public static void straightInsertSort(int[] a) { int elements = 1; //記錄結果集中元素的個數,起初只有a[0]這一個元素 for(int i=1;i<a.length;i++){ //從a[1]開始逐個插入 int j; for(j=0;j<elements;j++){ //遍歷結果集,逐次與a[i]作比較 if(a[j] > a[i]){ //若a[j] >a[i],則把結果集從最後位置(即a[elements-1])到j位置逐個向後移動一個位置 int temp = a[i]; //將要插入的值保留到temp中 for(int k =elements-1;k>=j;k--){ a[k+1] = a[k]; } a[j] = temp; //將要插入的值插入到j位置 elements++; //結果集元素的個數加1 break; } } if(j == elements){ //說明結果集中的元素都小於等於a[i],即將a[i]的值插入到末尾 a[elements] = a[i]; elements++; } } }
讓我們執行下面的測試程式碼,來看看我們寫的演算法吧。
public static void main(String[] args) {
int[] a = new int[]{5,3,9,7,6,18,1,16,15};
straightInsertSort(a);
for(int i =0;i<a.length;i++){
System.out.print(a[i]+ " ");
}
}
是不是與我們預期的一樣呢~既然我們已經學習了直接插入排序演算法,老規矩,來做個題練練手吧。
HDU 1106 排序
Problem Description
輸入一行數字,如果我們把這行數字中的‘5’都看成空格,那麼就得到一行用空格分割的若干非負整數(可能有些整數以‘0’開頭,這些頭部的‘0’應該被忽略掉,除非這個整數就是由若干個‘0’組成的,這時這個整數就是0)。 你的任務是:對這些分割得到的整數,依從小到大的順序排序輸出。
Input
輸入包含多組測試用例,每組輸入資料只有一行數字(數字之間沒有空格),這行數字的長度不大於1000。 輸入資料保證:分割得到的非負整數不會大於100000000;輸入資料不可能全由‘5’組成。
Output
對於每個測試用例,輸出分割得到的整數排序的結果,相鄰的兩個整數之間用一個空格分開,每組輸出佔一行。
Sample Input
0051231232050775
Sample Output
0 77 12312320
問題分析
我們可以將我們輸入的這串序列儲存在字串中,然後通過字串的split方法將'5'作為分隔符,將原序列分割為字串陣列,然後通過Integer.praseInt(String str)方法將陣列中的每個字串轉化為整數,然後用我們今天學習的直接插入排序演算法對這些整數進行排序就解決了。
程式碼
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String str = input.next(); //將我們輸入的序列儲存到字串str中
String[] strs = str.split("5"); //通過字串的split方法將5作為分隔符分割原序列
int[] result = new int[strs.length]; //定義陣列result儲存這些整數
for(int i =0;i<result.length;i++){ //通過Integer.parseInt(String str)方法將字串轉為整數
result[i] = Integer.parseInt(strs[i]);
}
straightInsertSort(result); //呼叫直接插入排序對陣列result進行排序
for(int i =0;i<result.length;i++) { //列印結果
System.out.print(result[i]+" ");
}
}
public static void straightInsertSort(int[] a) {
int elements = 1; //記錄結果集中元素的個數,起初只有a[0]這一個元素
for(int i=1;i<a.length;i++){ //從a[1]開始逐個插入
int j;
for(j=0;j<elements;j++){ //遍歷結果集,逐次與a[i]作比較
if(a[j] > a[i]){ //若a[j] >a[i],則把結果集從最後位置(即a[elements-1])到j位置逐個向後移動一個位置
int temp = a[i]; //將要插入的值保留到temp中
for(int k =elements-1;k>=j;k--){
a[k+1] = a[k];
}
a[j] = temp; //將要插入的值插入到j位置
elements++; //結果集元素的個數加1
break;
}
}
if(j == elements){ //說明結果集中的元素都小於等於a[i],即將a[i]的值插入到末尾
a[elements] = a[i];
elements++;
}
}
}
讓我們測試一下吧。
總述
通過本次學習,我們又學會一種基礎排序演算法——直接插入排序演算法,我們的演算法水平又前進了一小步呢ヾ(◍°∇°◍)ノ゙