資料結構之排序演算法(五)-直接插入排序,希爾排序,直接選擇排序
直接插入排序:時間複雜度:O(n^2)
基本演算法思路是:把後面待排序的記錄按其關鍵字的大小逐個插入到一個已經排好序的有序序列中,直到所有記錄插完為止,得到一個新的有序序列。(無序插入前面有序)
演算法步驟:對陣列a
1,設定監視哨a[i],將待插結果的值賦值給temp
2, 設定開始查詢的位置j=i-1;
3,在陣列j後面搜尋,如果temp<a[j],那麼將第j個記錄後移,直到temp>=a[j]
4,將temp插入到a[j+1]的位置
文字不行,直接上程式碼:
輸出:public class InsertSort { public static void main(String[] args) { int[] a={49,38,65,52,13,25,45,62,20}; insertSort(a); System.out.print("排序結果:"); for(int i=0;i<a.length;i++){ System.out.print(a[i]+" "); } } public static void insertSort(int[] a){ int temp=0; for(int i=1;i<a.length;i++){ int j=i-1; temp=a[i]; while(j>=0&&temp<a[j]){//temp比前邊的值小,前邊的值就依次後移 a[j+1]=a[j]; j--; } a[j+1]=temp;//注意要加1,插入正確位置 //每趟輸出 Output(a,i); } } public static void Output(int[] a,int i){ System.out.print("第"+i+"趟: "); for(int k=0;k<a.length;k++){ System.out.print(a[k]+" "); } System.out.println(); } }
第1趟: 38 49 65 52 13 25 45 62 20
第2趟: 38 49 65 52 13 25 45 62 20
第3趟: 38 49 52 65 13 25 45 62 20
第4趟: 13 38 49 52 65 25 45 62 20
第5趟: 13 25 38 49 52 65 45 62 20
第6趟: 13 25 38 45 49 52 65 62 20
第7趟: 13 25 38 45 49 52 62 65 20
第8趟: 13 20 25 38 45 49 52 62 65
排序結果:13 20 25 38 45 49 52 62 65
希爾排序:希爾排序又叫縮小增量排序。基本演算法思路是:先將整個待排序的記錄序列分割成為若干子序列分別進行直接插入排序,待整個序列中的記錄“基本有序”時,再對全體記錄進行依次直接插入排序。(說白了還是直接插入排序,只不過每次增量不一樣)
演算法步驟:
我們簡單處理增量序列:增量序列d = {n/2 ,n/4, n/8 .....1} n為要排序數的個數
即:先將要排序的一組記錄按某個增量d(n/2,n為要排序數的個數)分成若干組子序列,每組中記錄的下標相差d.對每組中全部元素進行直接插入排序,然後再用一個較小的增量(d/2)對它進行分組,在每組中再進行直接插入排序。繼續不斷縮小增量直至為1,最後使用直接插入排序完成排序。
程式碼:
public class ShellSort {
public static void main(String[] args) {
int[] a={49,38,65,52,13,25,45,62,20};
shellSort(a);
System.out.print("排序結果:");
for(int i=0;i<a.length;i++){
System.out.print(a[i]+" ");
}
}
public static void shellSort(int[] a){
int d=a.length/2;
while(d>=1){ //以各種不同的間隔距離d進行排序
//下面是直接插入排序
for(int i=d;i<a.length;i++){ //在某個d值下對各組進行排序
int j=i-d;
int temp=a[i];
while(j>=0&&temp<a[j]){ //按某個d值為間距進行組內比較
a[j+d]=a[j];
j-=d;
}
a[j+d]=temp;//插入正確的位置
}
d=d/2;
}
}
}
輸出結果:
排序結果:13 20 25 38 45 49 52 62 65
簡單選擇排序:時間複雜度O(n^2)
演算法基本思路:指每次從待排序的記錄中選出關鍵字最小(最大)的記錄,順序放入已排好序的有序序列中,直到全部排完
在要排序的一組數中,選出最小(或者最大)的一個數與第1個位置的數交換;然後在剩下的數當中再找最小(或者最大)的與第2個位置的數交換,依次類推,直到第n-1個元素(倒數第二個數)和第n個元素(最後一個數)比較為止。
演算法步驟:
第一趟,從n 個記錄中找出關鍵碼最小的記錄與第一個記錄交換;
第二趟,從第二個記錄開始的n-1 個記錄中再選出關鍵碼最小的記錄與第二個記錄交換;
以此類推.....
第i 趟,則從第i 個記錄開始的n-i+1 個記錄中選出關鍵碼最小的記錄與第i 個記錄交換,
直到整個序列按關鍵碼有序。
程式碼:
public class SelectSort {
public static void main(String[] args) {
int[] a={49,38,65,52,13,25,45,62,20};
seletSort(a);
System.out.print("排序結果:");
for(int i=0;i<a.length;i++){
System.out.print(a[i]+" ");
}
}
public static void seletSort(int[] a){
for(int i=0;i<a.length;i++){
int k=i;//開始的時候k和i指向一樣
int temp=a[i];
for(int j=i+1;j<a.length;j++){//在後邊找最小的,把k指向最小數的座標
if(a[j]<temp){
temp=a[j];
k=j;
}
}
if(k!=i){//如果k不等於i就交換
int t=a[i];
a[i]=a[k];
a[k]=t;
}
}
}
}
輸出結果:
排序結果:13 20 25 38 45 49 52 62 65
總結:
演算法複雜度的記法:
“三個簡單排序”
冒泡 O(n^2)
插入 O(n^2)
選擇 O(n^2)
“三個複雜排序”
快排 O(nlogn)
歸併O(nlogn)
堆排O(nlogn)
希爾排序:O(n^1.3)