java實現常見排序(選擇,冒泡,插入,快速,希爾,堆)
選擇排序
定義一個的標誌位temp,預設為比較的第一個數的下標,分別與後面的數進行比較,若比比較的數字大,則把該數的下標賦給temp,迴圈一次結束後判斷temp的值,若temp值跟第一個數的下標不一樣,則把第一個數跟下標為temp的值交換,若temp值一樣,則說明後面的數字都比第一個數大,則不交換,繼續下一次迴圈,以此類推,直到迴圈結束,具體實現的程式碼如下:
public class Main { public static void main(String[] args) { int array[] = new int[]{2,4,6,8,1,3,5,7,10,9}; int index,current; for(int i=0;i<array.length-1;i++){ index=i; for(int j=i+1;j<array.length;j++){ if(array[index]>array[j]){ index = j; } } if(index!=i){ current = array[i]; array[i] = array[index]; array[index] = current; } } } }
氣泡排序
氣泡排序,有一個口訣"大數沉底,小數往上飄",可見,氣泡排序每一次找出的都是當前需要排列的數字中的最大的那個值,那樣當所有的數都遍歷過後,也就從小到大排好了序,具體實現如下:
public class Main { public static void main(String[] args) { int array[] = new int[]{2,4,6,8,1,3,5,7,10,9}; int temp; for(int i=0;i<array.length;i++){ for (int j=0;j<array.length-1;j++){ if(array[j]>array[j+1]){ temp = array[j]; array[j] = array[j+1]; array[j+1] = temp; } } } } }
插入排序
插入排序,可以簡單理解為在打撲克,每次拿到一張新的牌子都會對手中的牌子做比較,找到對應該牌的位置後插入,那樣在手中的牌子則一直是排好序的。具體到陣列中的話,把陣列第一位數當作手中的牌,後面的數則是要插入的數字,插入排序最壞的執行時間是O(n2)。具體程式碼實現如下:
public class Main { public static void main(String[] args) { int array[] = new int[]{2,4,6,8,1,3,5,7,10,9}; int current,temp; //除去第一個數,後面均是要插入的數 for(int i=1;i<array.length;i++){ current = array[i]; //要插入的數 temp = i; //記錄插入數的位置 for(int j=i-1;j>=0;j--){ if(array[j]>current){ array[j+1] = array[j]; temp --; } } array[temp] = current; } } }
快速排序
快速排序採用了"二分"的思維。選用一個數作為基數(一般是陣列中的第一個數),從右往左找小於基數的數i,從左到右找大於基數的數j,若i!=j,則交換兩個數,若i==j,則退出當前迴圈,且array[i]與基數進行交換。這樣通過基數就形成了兩個區間,再重複以上操作,直到區間只剩下一個數字為止,最終實現小的數在基數的左邊,大的數在基數的右邊。具體實現程式碼如下:
public class Main {
public static void main(String[] args) {
int array[] = new int[]{2,4,6,8,1,3,5,7,10,9};
quickSort(array,0,array.length-1);
for (int i=0;i<array.length;i++){
System.out.print(array[i]+" ");
}
}
public static void quickSort(int[] array,int low,int high){
if(low<high){
int middle = sortUtil(array,low,high);
//左邊排序
quickSort(array,low,middle-1);
//右邊排序
quickSort(array,middle+1,high);
}
}
public static int sortUtil(int[] array,int low,int high){
int temp = array[low];
while(low<high){
//從右往左找到第一個比temp要小的值,交換
while (low<high && array[high]>temp){
high--;
}
array[low] = array[high];
//從左往右找到第一個比temp要大的值,交換
while (low<high && array[low]<temp){
low++;
}
array[high] = array[low];
}
array[low] = temp;
return low;
}
}
希爾排序
希爾排序沿用了插入排序的原理,同時也有"二分法"的思想在裡面。先將要排序的一組數按某個增量d(n/2,n為要排序數的個數)分成若干組,每組中記錄的下標相差d.對每組中全部元素進行直接插入排序,然後再用一個較小的增量(d/2)對它進行分組,在每組中再進行直接插入排序。當增量減到1時,進行直接插入排序後,排序完成。其中,以增量d一般為待排序的序列長度的一半。
public class Main {
public static void main(String[] args) {
int array[] = new int[]{2,4,6,8,1,3,5,7,10,9};
int j,temp;
for (int length=array.length/2; length>0; length/= 2) {
for (int i=length; i<array.length; i++) {
temp=array[i];
for (j=i-length;j>= 0;j-=length) {
if (temp<array[j]) {
array[j+length]=array[j];
} else {
break;
}
}
array[j + length] = temp;
}
}
}
}
堆排序
堆排序的基本思想是將待排序的序列構造成一個大頂堆(從上往下,從左往右數字逐漸減小)。此時,整個序列的最大值就是堆頂的根節點。將它與堆陣列的末尾元素交換,此時末尾元素就是最大值,然後將除去末尾元素的剩餘的 n-1 個序列重新構造成一個堆,這樣就會得到 n 個元素中次大的值。如此反覆執行,便能得到一個有序序列了。
public class Main {
public static void main(String[] args) {
int array[] = {2,4,6,8,1,3,5,7,10,9};
int i,temp;
for (i = array.length / 2 - 1; i >= 0; i--) {
// 構建一個大頂堆
adjust(array, i, array.length - 1);
}
for (i = array.length - 1; i >= 0; i--) {
// 將堆頂記錄和當前未經排序子序列的最後一個記錄交換
temp = array[0];
array[0] = array[i];
array[i] = temp;
// 將array中前i-1個記錄重新調整為大頂堆
adjust(array, 0, i - 1);
}
}
public static void adjust(int[] array, int i, int len) {
int temp,j;
temp = array[i];
for (j = 2 * i; j < len; j *= 2) {
if (j < len && array[j] < array[j + 1]){
++j;
}
if (temp >= array[j]){
break;
}
array[i] = array[j];
i = j;
}
array[i] = temp;
}
}