基本思想:將一個待排序的數插入到已排好序的關鍵字中,直到所有數排好。如 2 5 8 12 插入數7 則需要找到插入的位置即位置3,則需要移動8 12 移動元素後插入。
主要的排序算法:
說明:數組A[0]不放排序元素 從A[1]開始排序
1》直接插入排序算法
package suanfa;
public class InsertSort {
//核心算法
//A是待排序數組 n是表長
public void insertSort(int[] A,int n ){
int i,j;
for(i=2;i<=n;i++){
//待插入的數據A[i]大於A[i-1],則直接插入,反之則往前進行比較,
//選擇合適的插入的位置
if(A[i]<A[i-1]){
//A[0]僅是哨兵
A[0]=A[i];
//邊查找邊移動位置
for(j=i-1;A[i]<A[j];j--){
A[j+1]=A[j];
}
//找到插入位置
A[j+1]=A[0];
}
}
}
//測試
public static void main(String[] args) {
int[] A={0,2,12,6,8,11,31,18,27};
int n =A.length-1;
InsertSort insertSort = new InsertSort();
insertSort.insertSort(A, n);
for(int i=0;i<=n;i++){
System.out.println(A[i]);
}
}
}
直接插入排序算法可以看出是邊查找邊移動位置 是否可以減少查找次數呢?
2》折半插入排序
選擇一個待排序數插入一個序列時,這一個序列時有序的,那麼就可以想到折半查找(測試代碼都一樣,這裏只貼核心代碼)
//核心算法
//A是待排序數組 n是表長
public void insertSort(int[] A,int n ){
int i,j,low,high,mid;
for(i=2;i<=n;i++){
A[0]=A[i];//將待排序數放到A[0]暫存
low=1;
high=i-1;
//1.先利用折半查找找到插入的位置(查找和移動位置是分開進行的)
while(low<=high){
mid=(low+high)/2;
if (A[mid]>A[0]) high=mid-1;
else low=low+1;
}
//2.找到插入位置,移動元素
for(j=i-1;j>=high+1;j--){
A[j+1]=A[j];
}
//2.將待排元素插入
A[high+1]=A[0];
}
}
與直接插入排序比較,只是減少了比較的次數,但是移動次數是沒有變的
3》再說一種排序算法 希爾排序
什麼是希爾排序算法:(自己理解的)希爾排序本質上就是直接插入排序,從一個例子來看:
希爾排序就是將原數組先劃分爲幾個小組,分別排序,然後將增量減小再分組 ,再排序 直到增量爲1,排序就完成了。所以希爾排序我們要知道增量怎麼確定,一般增量d1=n/2;d2=d1/2;.......
//核心算法
//A是待排序數組 n是表長
public void ShellSort(int[] A,int n ){
int i,j,d;//d是增量
//注意和直接插入排序進行比較 實際上是多了一層for循環 這一層循環就是分組排序的次數
for(d=n/2;d>=1;d=d/2){
//這一個for循環和直接插入排序算法基本是一樣的 (把d換成1)
for(i=d+1;i<=n;i++){
if(A[i]<A[i-d]){
A[0]=A[i];
for(j=i-d;j>0&&A[0]<A[j];j=j-d){
A[j+d]=A[j];
}
A[j+d]=A[0];
}
}
}
}
插入排序:找到插入位置---移動元素---插入元素 基本就是這三個步驟