交換排序(氣泡排序~快速排序~)+插入排序(直接插入排序~希爾排序~)
一、氣泡排序
1、基本概念
依次比較相鄰的兩個數,將小數放在前面,大數放在後面。
第一趟:首先比較第1個數和第2個數,將小數放前,大數放後;然後比較第2個數和第3個數,將小數放前,大數放後;如此繼續,直至比較最後兩個數,將小數放前,大數放後;至此第一趟結束,使得最後一個數字是最大的了!
第二趟:仍從第一對數開始比較,將小數放前,大數放後,一直比較到倒數第二個數字,(倒數第一的位置已經是最大的了),第二趟結束,在倒數第二個位置上得到了一個新的最大的數字(整個陣列當中第二大數字)!
如此過程,重複進行下去,直達最終完成排序。
2、實現思路
使用二重迴圈實現,外變數設為i,內部變數設為j。假如有n個數據要進行排序,則外迴圈重複n-1次,內部迴圈依次重複n-1,n-2,......1次,外部迴圈控制執行的趟數,內部迴圈控制比較的數字,每次比較的兩個數字都是與j有關,分別可以用a[j]和a[j+1]來識別,i的值依次為1,2,......,n-1,對於每一個i,j的值依次為1,2,......,n-i。
舞蹈之氣泡排序:http://v.youku.com/v_show/id_XMzMyOTAyMzQ0.html?from = s1.8-1-1.2
時間複雜度:最壞情況:O(n ^ 2)、最好情況:O(n)
空間複雜度:O(1)
程式碼演示:
/* * 氣泡排序 */ public static<T> void Swap(T [] arr,int i,int j){ T temp=arr[i]; arr[i]=arr[j]; arr[j]=temp; } public static<T extends Comparable<T>> void ButtleSort(T[] arr){ int len=arr.length; for(int i=0;i<len;i++){ for(int j=0;j<len-i-1;j++){ if(arr[j].compareTo(arr[j+1])>0){ Swap(arr,j,j+1); } } } }
二、快速排序(對氣泡排序的一種改進)
1、演算法思想
首先從陣列當中選擇出一個數字作為基準數字;分割槽過程,將比基準大的數字全部放在基準的右邊,比基準小的數字放在基準的左邊;再對左右區間重複第二步,直到各區間只有一個數字為止!
2、時間複雜度:O(n * logn)
最壞:O(n ^ 2)
空間複雜度:O(n * logn)
舞蹈之快速排序:http://v.youku.com/v_show/id_XMzMyODk4NTQ4.html?from = s1.8-1-1.2
程式碼演示:
/* * 快速排序 */ public static<T extends Comparable<T>> int quickSort(T[] arr,int low,int high){ T temp=arr[low]; //將陣列中的第一個數字作為基準 while(low<high){ while(low<high && arr[high].compareTo(temp)>=0){ high--; } arr[low]=arr[high]; //找到比基準小的數字挪動到左邊 while(low<high && arr[low].compareTo(temp)<0){ low++; } arr[high]=arr[low]; //找到比基準大的數字挪動到右邊 } arr[low]=temp; //最後將基準放到空出來的位置 return low; //返回基準的最終位置 } public static<T extends Comparable<T>> void quick(T[] arr,int low,int high){ if(low < high){//將陣列一分為二,進行遞迴呼叫 int pos=quickSort(arr,low,high); quick(arr,low,pos-1); quick(arr,pos+1,high); } }
三、直接插入排序
1、演算法思想
直接插入排序演算法的思想是將一個記錄插入到已經排好序的表中,從而得到一個新的、記錄數增1的有序表。對於給定的一組記錄,初始時假定第一個資料自成一個有序序列,其餘記錄為無序的序列。接著從第二個記錄開始,按照記錄的大小依次將當前處理的記錄插入到其之前的有序序列中,直到最後一個記錄插入到有序的序列中為止。
2、演算法步驟
首先從第一個元素開始,該元素被假定為有序的;取出下一個元素,在已經排好序的陣列中從前往後遍歷;如果該元素(已排序)大於新元素,則將該元素移到下一個位置;重複上一步,直到找到已排序的元素小於或者大於新元素的位置;將新元素插入到該位置;重複進行下去。
舞蹈之插入排序:http://v.youku.com/v_show/id_XMzMyODk3NjI4.html?from = s1.8-1-1.2
時間複雜度:最好的情況:O(n)、最壞的情況:O(n ^ 2)
空間複雜度:O(1)
程式碼演示:
/*
* 插入排序
*/
public static<T extends Comparable<T>> void insertSort(T[] arr){
int i,j;
T NoteNumber;//要插入的資料
for(i=1;i<arr.length;i++){
NoteNumber=arr[i];//迴圈將陣列中的資料作為要插入的新元素
j=i-1;
while(j>=0 && arr[j].compareTo(NoteNumber)>0){//插入的資料小於第j個元素,將資料進行向後挪動
arr[j+1]=arr[j];
j--;
}
arr[j+1]=NoteNumber;//直到插入的資料小於第j個元素,進行插入!
}
}
四、希爾排序
1、演算法思想
希爾排序是一種插入排序,又被稱為縮小增量排序。希爾排序的演算法思想就是:將資料進行分組,然後對每一組資料進行排序,在每一組資料有序後,就可以對所有的分組利用插入排序進行最後一次的排序,這樣可以達到減少交換的次數,達到加速的目的。
2、演算法演練
假定待排序的陣列有10條記錄,其分別為40、38、65、97、76、13、27、49、55、4。
步長取值分別為5,3,1
時間複雜度:最好的情況:O(n) 最壞的情況下:O(n ^ 2)
空間複雜度:O(1)
舞蹈之希爾排序:http://v.youku.com/v_show/id_XMzMyODk5MzI4.html?from = s1.8-1-1.2
排序過程如下:
程式碼演示:
/*
* 希爾排序
*/
public static<T extends Comparable<T>> void shellSort(T[] arr){
T temp;
int step=arr.length;
while(true){
step=step/2; //預設步長為陣列的長度除以2
for(int i=0;i<step;i++){//確定分組數
for(int j=i+step;j<arr.length;j=j+step){//對分組的資料進行直接插入排序
temp=arr[j];
int k=0;
for(k=j-step;k>=0;k=k-step){
if(arr[k].compareTo(temp)>0){
arr[k+step]=arr[k];
}else{
break;
}
}
arr[k+step]=temp;
}
}
if(step==1){
break;
}
}